Skip to content

Commit

Permalink
Feature: Nested formatting inside of List spacers (axuno#280)
Browse files Browse the repository at this point in the history
* Added NestedFormatSpacers test.
* Support nested formatting of spacers.
* Removed the null handling as theres no way parameters.Count could be less than 2 as we exit out earlier in the code.
* Remove redundant using statement.
* Small change based on PR feedback. Use the root arguments instead of the item when formatting the spacer.
  • Loading branch information
karljj1 authored May 12, 2022
1 parent 7a50b7e commit ea51956
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 6 deletions.
10 changes: 10 additions & 0 deletions src/SmartFormat.Tests/Extensions/ListFormatterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,16 @@ public void FormatTest(string format, string expected)

}

[Test]
public void NestedFormatSpacers()
{
var smart = Smart.CreateDefaultSmartFormat();
var names = new[] { "John", "Mary", "Amy" };

Assert.AreEqual("John, Mary and Amy", smart.Format("{0:list:{}|{1} | {2} }", names, ",", "and"));
Assert.AreEqual("John, Mary nor Amy", smart.Format("{Names:list:{}|, | {Not:nor|or} }", new { Names = names, Not = true }));
}

[TestCase("{0:list:{}-|}", "A-B-C-D-E-")]
[TestCase("{0:list:{}|-}", "A-B-C-D-E")]
[TestCase("{0:list:{}|-|+}", "A-B-C-D+E")]
Expand Down
32 changes: 26 additions & 6 deletions src/SmartFormat/Extensions/ListFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,9 @@ public bool TryEvaluateFormat(IFormattingInfo formattingInfo)
// itemFormat|spacer|lastSpacer
// itemFormat|spacer|lastSpacer|twoSpacer
var itemFormat = parameters[0];
var spacer = parameters.Count >= 2 ? parameters[1].GetLiteralText() : string.Empty;
var lastSpacer = parameters.Count >= 3 ? parameters[2].GetLiteralText() : spacer;
var twoSpacer = parameters.Count >= 4 ? parameters[3].GetLiteralText() : lastSpacer;
var spacer = parameters[1];
var lastSpacer = parameters.Count >= 3 ? parameters[2] : spacer;
var twoSpacer = parameters.Count >= 4 ? parameters[3] : lastSpacer;

if (!itemFormat.HasNested)
{
Expand Down Expand Up @@ -230,6 +230,18 @@ public bool TryEvaluateFormat(IFormattingInfo formattingInfo)
.Initialize(null, formattingInfo.FormatDetails, format, null);
spacerFormattingInfo.Alignment = 0;

// Note:
// Give spacers the data context of the root parent.
// formattingInfo.CurrentValue from the argument to
// TryEvaluateFormat(IFormattingInfo formattingInfo) only contains the list elements.
var rootParent = (formattingInfo as Core.Formatting.FormattingInfo);
do
{
rootParent = rootParent?.Parent;
} while (rootParent?.Parent != null);

var rootParentValue = rootParent?.CurrentValue;

foreach (var item in items)
{
CollectionIndex += 1; // Keep track of the index
Expand All @@ -241,15 +253,15 @@ public bool TryEvaluateFormat(IFormattingInfo formattingInfo)
}
else if (CollectionIndex < items.Count - 1)
{
spacerFormattingInfo.Write(spacer);
WriteSpacer(spacerFormattingInfo, spacer, rootParentValue);
}
else if (CollectionIndex == 1)
{
spacerFormattingInfo.Write(twoSpacer);
WriteSpacer(spacerFormattingInfo, twoSpacer, rootParentValue);
}
else
{
spacerFormattingInfo.Write(lastSpacer);
WriteSpacer(spacerFormattingInfo, lastSpacer, rootParentValue);
}

// Output the nested format for this item:
Expand All @@ -268,6 +280,14 @@ public bool TryEvaluateFormat(IFormattingInfo formattingInfo)
return true;
}

private static void WriteSpacer(IFormattingInfo formattingInfo, Format spacer, object? value)
{
if (spacer.HasNested)
formattingInfo.FormatAsChild(spacer, value);
else
formattingInfo.Write(spacer.GetLiteralText());
}

/// <summary>
/// Checks if any of the <see cref="Placeholder"/>'s <see cref="Placeholder.Selectors"/> has nullable <c>?</c> as their first operator.
/// </summary>
Expand Down

0 comments on commit ea51956

Please sign in to comment.