Skip to content

Commit bd3d832

Browse files
author
JJJ
committed
dding support for quoting with back ticks
1 parent f52b28a commit bd3d832

2 files changed

Lines changed: 42 additions & 8 deletions

File tree

src/SmartFormat.Tests/Extensions/DictionaryFormatterTests.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public object[] GetArgs()
2626
{"A", "a"},
2727
{"B", "b"},
2828
{"C", "c"},
29+
{"Name.with.dot", "d"}
2930
}},
3031
{"Object", new {
3132
Prop1 = "a",
@@ -60,11 +61,13 @@ public void Test_Dictionary()
6061

6162
var formats = new string[] {
6263
"Chained: {0.Numbers.One} {Numbers.Two} {Letters.A} {Object.Prop1} ",
63-
"Nested: {0:{Numbers:{One} {Two}} } {Letters:{A}} {Object:{Prop1}} ", // Due to double-brace escaping, the spacing in this nested format is irregular
64+
"Nested: {0:{Numbers:{One} {Two}} } {Letters:{A}} {Letters:{Name.with.dot}} {Object:{Prop1}} ", // Due to double-brace escaping, the spacing in this nested format is irregular
65+
@"{Letters.`Name.with.dot`}", // Due to double-brace escaping, the spacing in this nested format is irregular
6466
};
6567
var expected = new string[] {
6668
"Chained: 1 2 a a ",
67-
"Nested: 1 2 a a ",
69+
"Nested: 1 2 a d a ",
70+
"d",
6871
};
6972
var args = GetArgs();
7073
formatter.Test(formats, args, expected);

src/SmartFormat/Core/Parsing/Parser.cs

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public Parser(ErrorAction errorAction)
5454
/// </summary>
5555
private char AlternativeEscapeChar = '\\';
5656

57+
private char QuoteChar = '`';
5758
/// <summary>
5859
/// Includes a-z and A-Z in the list of allowed selector chars.
5960
/// </summary>
@@ -132,32 +133,43 @@ public Format ParseFormat(string format)
132133
int lastI = 0;
133134
int operatorIndex = 0;
134135
int selectorIndex = 0;
136+
bool inQuotedText = false;
137+
char lastChar = (char)0;
138+
char c = (char)0;
135139
for (int i = 0, length = format.Length; i < length; i++)
136140
{
137-
var c = format[i];
141+
lastChar = c;
142+
c = format[i];
138143
if (currentPlaceholder == null)
139144
{
140145
if (c == '{')
141146
{
147+
var startIndex = i;
142148
// Finish the last text item:
143149
if (i != lastI)
144150
current.Items.Add(new LiteralText(current, lastI) { endIndex = i });
145151
lastI = i + 1;
146152

153+
var nextI = lastI;
147154
// See if this brace should be escaped:
148155
if (!this.AlternativeEscaping)
149156
{
150-
var nextI = lastI;
151157
if (nextI < length && format[nextI] == '{')
152158
{
153159
i++;
154160
continue;
155161
}
156162
}
157163

164+
if( nextI < length && format[nextI] == QuoteChar )
165+
{
166+
inQuotedText = true;
167+
i++;
168+
lastI++;
169+
}
158170
// New placeholder:
159171
nestedDepth++;
160-
currentPlaceholder = new Placeholder(current, i, nestedDepth);
172+
currentPlaceholder = new Placeholder( current, startIndex, nestedDepth );
161173
current.Items.Add(currentPlaceholder);
162174
current.HasNested = true;
163175
operatorIndex = i+1;
@@ -212,23 +224,40 @@ public Format ParseFormat(string format)
212224
else
213225
{
214226
// Placeholder is NOT null, so that means we're parsing the selectors:
227+
if( inQuotedText )
228+
{
229+
inQuotedText = c != QuoteChar;
230+
}
231+
else
232+
{
233+
var endIndex = i;
234+
if( i > 0 && lastChar == QuoteChar )
235+
{
236+
endIndex = i-1;
237+
}
215238
if (Operators.IndexOf(c) != -1)
216239
{
217240
// Add the selector:
218241
if (i != lastI)
219242
{
220-
currentPlaceholder.Selectors.Add(new Selector(format, lastI, i, operatorIndex, selectorIndex));
243+
currentPlaceholder.Selectors.Add( new Selector( format, lastI, endIndex, operatorIndex, selectorIndex ) );
221244
selectorIndex++;
222245
operatorIndex = i;
223246
}
224247

225248
lastI = i + 1;
249+
if( lastI < length && format[lastI] == QuoteChar )
250+
{
251+
inQuotedText = true;
252+
i++;
253+
lastI++;
226254
}
255+
}
227256
else if (c == ':')
228257
{
229258
// Add the selector:
230259
if (i != lastI)
231-
currentPlaceholder.Selectors.Add(new Selector(format, lastI, i, operatorIndex, selectorIndex));
260+
currentPlaceholder.Selectors.Add( new Selector( format, lastI, endIndex, operatorIndex, selectorIndex ) );
232261
else if (operatorIndex != i)
233262
{
234263
// There are trailing operators. For now, this is an error.
@@ -247,7 +276,7 @@ public Format ParseFormat(string format)
247276
{
248277
// Add the selector:
249278
if (i != lastI)
250-
currentPlaceholder.Selectors.Add(new Selector(format, lastI, i, operatorIndex, selectorIndex));
279+
currentPlaceholder.Selectors.Add( new Selector( format, lastI, endIndex, operatorIndex, selectorIndex ) );
251280
else if (operatorIndex != i)
252281
{
253282
// There are trailing operators. For now, this is an error.
@@ -261,6 +290,7 @@ public Format ParseFormat(string format)
261290
currentPlaceholder.endIndex = i + 1;
262291
current = currentPlaceholder.parent;
263292
currentPlaceholder = null;
293+
inQuotedText = false;
264294
}
265295
else
266296
{
@@ -275,6 +305,7 @@ public Format ParseFormat(string format)
275305
// Invalid character in the selector.
276306
parsingErrors.AddIssue(current, "Invalid character in the selector", i, i + 1);
277307
//ParserError(format, i, "Invalid character in the selector", result);
308+
}
278309
}
279310
}
280311
}

0 commit comments

Comments
 (0)