axuno / SmartFormat

A lightweight text templating library written in C# which can be a drop-in replacement for string.Format
Other
1.1k stars 105 forks source link

Pipe character literal in ListFormatter #96

Closed gab closed 6 years ago

gab commented 7 years ago

Hi! First of all thanks for SmartFormat, it's a pretty nifty library.

I've been trying various ways of using the pipe character | as a separator when using the ListFormatter, the desired final output text being: item1|item2|item3

However this seems impossible , there's no way of escaping that character. There doesn't seem to be a way of using nested braces to insert a variable to be used as spacer, either.

Is this as designed, or could it be fixed?

Thanks!

axunonb commented 7 years ago

This is by design. The ListFormatter currently has the pipe character hard coded: var parameters = format.Split('|', 4); Giving the ability to choose a random character would require to test for valid characters which do not interfere with the general functionality of Smart.Format. This would have to become a part of the extension interface. If you have a proposal how to accomplish that, we could implement to the standard library. Otherwise: To use the pipe character in the output you could supply your custom extension with a different character for parameter separation.

gab commented 7 years ago

I would suggest that you simply do like regexes: you can prefix any character with backslash \ and it means that the next character must be interpreted as a literal. You already do it for braces with an option enabled, I think you should just make it standard and always-on, it can live alongside brace-escaping. Extensions can do whatever they want as long as they follow the escaping rules, they just have to inform the user of whatever reserved characters they add to the list of those that can interfere with functionality.

So for instance, the following line of code: Smart.Format(@"{0:list:{}| \| }", new object[] { new[] { "one", "two", "three" } }); or the equivalent: Smart.Format("{0:list:{}| \\| }", new object[] { new[] { "one", "two", "three" } }); would output: one | two | three

Also, making templates work recursively to allow something like this would be pretty cool and could make format strings more readable by moving complicated parts to separate variables: Smart.Format(@"{0:list:{}|{1}}", new object[] { new[] { "one", "two", "three" } }, @"<{|}>"); Output: one<{|}>two<{|}>three (Intentionally silly/overcomplicated example.)

On my end unfortunately after re-evaluating my requirements I think I'll have to go with a more heavyweight templating engine. But I'll be following any developments on this project with interest!

axunonb commented 7 years ago

Thanks for your comments. Indeed, general escaping could be considered, if there was not the existing standard escaping for \n, \t, { and alike, that interferes. So having a public property for the "split character" of ListFormatter seems as an obvious option. This again is not bullet-proof related to configurable special characters for the parser. More thoughts needed for a solid solution.

axunonb commented 6 years ago

Would involve too many breaking changes.