axuno / smartformat Goto Github PK
View Code? Open in Web Editor NEWA lightweight text templating library written in C# which can be a drop-in replacement for string.Format
License: Other
A lightweight text templating library written in C# which can be a drop-in replacement for string.Format
License: Other
Hi,
I was playing with Choose option and I noticed that the output was not the desired one and I tried then the examples in https://github.com/scottrippey/SmartFormat.NET/wiki/Choose
This is some code to exemplify the issue:
var number = 1;
var boolean = true;
var c1 = Smart.Format("The number is {0:choose(1,2,3):one|two|three|other}", number);
var c2 = Smart.Format("The number is {0:choose(1,2,3):one|two|three|other}", 2);
var c3 = Smart.Format("The number is {0:choose(true,false):bigger|smaller}", true);
var c4 = Smart.Format("The number is {0:choose(true,false):bigger|smaller}", "true");
var c5 = Smart.Format("The number is {0:choose(true,false):bigger|smaller}", boolean);
c1, c2 and c3 are always: The number is
c4 and c5 are always: The number is smaller
Version used is
<package id="SmartFormat.NET" version="1.5.0.0" targetFramework="net452" />
I hope that information helps,
Thanks!
Hi
I'm allowing users to edit format strings in an HTML editor. This works well until they use characters that require encoding, e.g.
{Contacts.Count::>0?<ul>{Contacts:<li>{FirstName} {LastName}</li>|}</ul>|}
Can you suggest a way I can decode the HTML which needs formatting without effecting encoded HTML outside the format regions? I can access the text nodes using HtmlAgilityPack.
SmartFormat.NET is an outstanding piece of work by the way.
Thank you
Andrew
A question on StackOverflow has brought me to explain how nested "scopes" work, and I'm thinking about ways to make it better.
For the following examples, assume we have data like this:
People = [ { First, Last, Age }, { First, Last, Age } ... ]
Currently, when you use nesting, the "scope" of the nesting is changed to the current value. For example:
Nested: "{People.0: {First} {Last} {Age}}"
Unnested: "{People.0.First} {People.0.Last} {People.0.Age}"
This was intentionally designed to be used with list formatting, and usually works for pluralization:
List: "{People: {First} {Last} {Age} |, }"
Plural: "There {People.Count: is a person | are {} people }"
However, the problem is that each "nesting" can only use a single value, so it's hard to do any formatting that uses 2 values. This makes Conditional formatting much harder. In order to use the "root scope", you can use {0.
..., so this provides a workaround for some scenarios.
I'd like to simply discuss if there's a better approach for "nested" scopes?
Ideas:
{$root.Value}
instead of {0.Value}
("Explicit Ancestors"){..Value}
to pop "up" the scope as far as we need (also "Explicit Ancestors").
... for example: {Items: {.Name} | and }
("Explicit Nesting"){RootProp1: {NestedProp1} {RootProp2: {NestedProp2} {NestedProp1} {RootProp1}} }
I agree. Custom extensions should always be executed before the built in ones. else they would not be called for common data types.
I've created a Date extension which was not being called when following the wiki guideline:
Smart.Default.AddExtensions(new DateFormatter());
However, if I do this:
Smart.Default.FormatterExtensions.Insert(0, new DateFormatter());
everything works OK. But many new users might not explore the library to discover that. Insert custom extensions before the default ones.
I have a custom named formatter called strbool
. Which prints Yes if value is true and prints No if value is false.
In the previous version, this works fine.
Smart.Format("{value:strbool}", new { value = true });
Now it needs a parenthesis.
Smart.Format("{value:strbool()}", new { value = true });
What it means adding a parenthesis here? Again previous syntax felt more natural.
Hi,
Does SmartFormat support functionality like the null-coalescing operator? Except that it should work more like the String.IsNullOrWhiteSpace
method. See below for what I mean:
var info = new {
Name = "",
Title = "Commander"
};
// I'm looking for a conditional selection of tokens like this:
Console.WriteLine(Smart.Format("Info: '{Name|Title|}'", info));
// That would be equivalent to the following:
Console.WriteLine(Smart.Format("Info: '{0}'", !String.IsNullOrWhiteSpace(info.Name)
? info.Name
: !String.IsNullOrWhiteSpace(info.Title)
? info.Title
: ""));
Thanks!
I do not understand from the Conditional Formatting Syntax chapter how to test for null values of numeric properties.
This is an example that doesn't produce expected result:
using System;
using SmartFormat;
public class Point
{
public double? Lat { get; set; }
public double? Lon { get; set; }
}
public class Program
{
public static void Main()
{
var point = new Point {Lat = 23.45};
Console.WriteLine(Smart.Format("Latitude: {Lat:{}|N/A}, longitude: {Lon:{}|N/A}", point));
// Output is:
// Latitude: N/A, longitude: N/A
// Output I want is:
// Latitude: 23.45, longitude: N/A
}
}
You can run it in this fiddle.
Take a look at this nice logging library here:
https://github.com/serilog/serilog
I am using both for my logging and would like to suggest you perhaps take advantage of ideas or implementation of that library. Honestly it is sometimes confusing to me which string formatting i am supposed to use. it is my little pipe dream of having both libraries using the same syntax
After upgrading to version 1.6.1, formatting the time with a colon no longer works:
class Program
{
class Example
{
public Example()
{
Time = DateTime.UtcNow;
}
public DateTime Time { get; set; }
}
static void Main( string[] args )
{
var template = "Time: {Time:HH:mm} Date: {Time:ddd dd/MM}.";
var text = Smart.Format( template, new Example() );
// outputs: Time: Date: Sun 21/06.
Console.WriteLine( text );
Console.ReadLine();
}
}
I ran into this issue when trying to get this project rolling in my app by downloading the source here and building it without fully reading the wiki. I was using SmartFormatter.Format instead of using Smart.Format, so it was throwing the error "No source extensions are available. Please add at least one source extension, such as the DefaultSource". On that note, I eventually wiped my manual install and used your nice NuGet package instead.
Any ways, it was a moment of /facepalm when I realized my issue. Perhaps you could add this into the wiki somewhere? And perhaps solutions to all of the thrown errors?
Thanks for an amazing little project. I'm using it now and it's quick and convenient. 👍
As a result of previous discussions, I think the best approach to nested scopes is to create a "scope stack".
When you are in a nested template, all Selectors are evaluated "down the stack" -- so if the Selector can't be resolved by the top item, it will attempt to resolve using the next item in the stack, and so on.
(This is very similar to how AngularJS works)
This will also allow for some extensions to insert values into the stack, which can be particularly useful for the List formatter.
Anyway, this "issue" is just to track this change, to consolidate some threads, and to discuss any details that might come up.
Hi,
I would like to use this Library in my Windows Store / Phone App but it is currently build for the "old" .Net 3.5 and is not PCL ready.
Anyway, I could port it, but would you merge it, once I'm done with the port, so that It'll be available via NuGet?
Hello,
Could you deploy a NuGet package for SmartFormat? I'll be using it to create a SmartFormat plugin to handle natural date tokens. :)
With #7 merged, we can deploy a NuGet package like this:
cd SmartFormat.NET\src\SmartFormat
nuget.exe pack
SmartFormat.NET.1.0.0.0.nupkg
to nuget.org.In "Release" mode, the default ErrorAction
is Ignore
.
This often results in a lot of confusion, especially since NuGet delivers the Release build.
So, a better default ErrorAction
should be chosen.
Choices are Ignore
, ThrowError
, MaintainTokens
, or OutputErrorInResult
.
In "Debug" mode, the default ErrorAction
is ThrowError
, which is appropriate.
Currently, the Named Formatter syntax (eg. {0:formatter:format}
) is interfering with valid formats, such as {Date:hh:mm:ss}
.
(continued from #27)
Here's a code snippet you can try for yourself. It's not giving expected output.
void Main()
{
var template2 = "[ {Name:name:|{0.Title:tilte:|name:}} {Name:{}|{0.Title:{}|n/a}} ]";
var info1 = new { Name = "A", Title = "" };
var info2 = new { Name = "", Title = "B" };
var info3 = new { Name = "", Title = "" };
Console.WriteLine(Smart.Format(template2, info1)); // [ name:
Console.WriteLine(Smart.Format(template2, info2)); // [ tilte:
Console.WriteLine(Smart.Format(template2, info3)); // [ name:} n/a} ]
// Output I want is:
// [ name: A ]
// [ title: B ]
// [ name: n/a ]
}
You can run it in this fiddle.
Hello,
I am translating GitExtensions, which use SmartFormat.NET
There are some texts like "{0} {1:month|months} ago".
But for Polish I need 3 forms like:
"nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"
(for example .po of FileZilla - 1 / 2, 3, 22 ... / 0, 5, 6, 7...)
or something like that: http://www.mediawiki.org/wiki/Localisation#.E2.80.A6on_numbers_via_PLURAL
So I could write "{0} {1:miesiąc|miesiące|miesięcy} temu". For now I have to use unclean "{0} {1:miesiąc|miesięc(e/y)} temu" :/
Could you try add this?
Thanks in advance,
Greetings, Maciej
I love this project, but I've been away from .NET development for 2 years now, and I'm not really able to manage pull requests, feature requests, and NuGet publishing.
I'd like this project to keep kicking, but I'll need some help.
@SeriousM @Pathoschild @lostdev @qstarin
I'd be happy to add you guys as contributors, if you're interested.
Is it possible to do math on DateTime objects?
Given the following:
Start: DateTime
End: DateTime
I'm looking to do the following operations:
{{Start-1}}
{{End-Start}}
Is this possible?
Thanks
marc
Smart.Format("{A:plan(s)|bar}", new{ A = true });
expected: plan(s)
result: empty string
Hey,
I don't understand the sentence Localization: Smart.Format uses the current culture info for formatting [...] in the wiki (page Is Smart.Format compatible with String.Format?).
According to me, it uses the English language by default: check the code of the method CreateDefaultSmartFormat in the class Smart. The string "en" is set manually!
Maybe that it could be better to use System.Threading.Thread.CurrentThread.CurrentUICulture.ToString()
, no? (in order to use the uiCulture parameter of globalization in the Web.config file).
In v1.5, the "named formatter" feature was introduced. However, the double-colon syntax was not fully backwards compatible, and introduced too many breaking changes.
The proposed solution is to use a similar syntax to the "alignment" syntax. Instead of double-colon, we'd use comma-colon:
{selector,formatter:format}
Examples:
{Name,choose(null):Hi,|Hi {Name} }
{Date,default:hh:mm:ss}
{Dates,list:hh:mm:ss|, }
This should certainly be fully compatible with String.Format
, and since the alignment feature can only be used with the default
formatter, it seems like a good fit.
This will solve many of the "named formatter" bugs.
This unit test fails from version 1.3.
[TestFixture]
class Tests
{
[TestCase(true, "yes (probably)")]
[TestCase(false, "no (possibly)")]
public void TestWithParens(bool value, string expected)
{
Assert.AreEqual(expected, Smart.Format("{value:yes (probably)|no (possibly)}", new {value }));
}
}
Expected string length 13 but was 0. Strings differ at index 0.
Expected: "no (possibly)"
But was: <string.Empty>
This code demonstrates the issue and inconsistency with String.Format
.
string name = null;
var str1 = String.Format("Name: {0,-10}| Column 2", name);
var obj = new { name };
var str2 = Smart.Format("Name: {name,-10}| Column 2", obj);
Console.WriteLine(str1); // output: "Name: | Column 2"
Console.WriteLine(str2); // output: "Name: | Column 2"
Set name to empty string and then it works correctly. Null value here should give the same result as empty string as it is the case with String.Format
.
Hi, thanks for this great library. Can you please strong-sign it in the nuget package? It is needed when other strong signed assemblies reference SmartFormat.dll
. Currently I'm using this workaround but it would be great if it is strong-signed by the author.
Thanks!
I have a proposition for an improved syntax for SmartFormat, and want feedback before jumping in.
{0:plural:singular|plural}
{0:choose:{}|null}
{0:list:{}|,}
{0:timespan:}
{0:default:N2}
{0:plural(en):singular|plural}
{0:choose(Male,Female):his|her}
{0:choose(<0,0,>0):negative|zero|positive}
{0:list(5):{}|,|, and |, and {} more}
{0:timespan(noless week):}
My thoughts:
choose
and list
, and enables plural
to specify the ruleset.choose
and list
) were intermingled, and the syntax was way too complicated. This syntax will be much easier to document, and makes much better sense.We started this discussion in #16, so I wanted to get feedback before I started these improvements.
I think I'd like to target v1.3 for this one, since it's such a significant change.
Hi
Currently you can assess a string using the smart formatter and decide it's usage like so;
{Keywords: {}|}
I was wondering if in the future more complex logic could be used so something like the below could be used;
{Keywords && Location: some example test|}
Currently I have a boolean return from a property which does this assessment for me so my format is still neat but I would love to get this all inline.
Love the library btw, it's really helped cut down my codebase.
Thanks!
Smart.Format("{0:HH:mm:ss}", DateTime.Now) == "" instead of valid string with current time
Hi
I just used the latest version of SmartFormat in a .Net 3.5 project and the dll from the .Net 3.5 profile doesn't seem to be a valid .Net 3.5 dll? The runtime referenced in the properties of the reference in the project is set to 4.0. Just thought I'd let you know.
Thanks
R
I just found this amazing library today and I have a use case where I currently use reflection to iterate over the properties of a complex object and format the property name and value into strings that then written to a log file for troubleshooting. The method listed below is my current implementation which is a method on my BaseClass object which all other objects in my project inherit from. While I use this function extensively throughout my projects I would much rather have a simple one or two line alternative that would make it easier for the others to read/use when implementing objects created from my base object. Does SmartFormat.NET provide the syntactic sugar for something similar in functionality, either native or via an extension method?
John
/// <summary>
/// Provides a formatted output of all object properties and values using reflection.
/// Example: {"PropertyA" : "PropertyAValue"}, {"PropertyB" : "PropertyBValue"}
/// </summary>
/// <returns>
/// Formatted string of property names/values
/// </returns>
public new string ToString()
{
const int itemsPerLine = 5;
var t = GetType();
var props = t.GetProperties();
var className = t.Name;
var returnValue = Environment.NewLine + className + Environment.NewLine;
var propertiesGroup = from i in Enumerable.Range(0, props.Count())
group props[i] by i / itemsPerLine;
var lastProperty = props.Last();
foreach (var property in propertiesGroup)
{
foreach (var propertyInfo in property)
{
var value = propertyInfo.GetValue(this, new object[] { });
returnValue += "{\"" + propertyInfo.Name + "\" : \"" + value + "\"}";
if (!propertyInfo.Equals(lastProperty))
returnValue += ", ";
}
returnValue += Environment.NewLine;
}
return returnValue;
}
Apologies this is my first post to Github and I was not able to figure out how to submit this item and apply the help tag. Can a moderator/admin please tag this post as a help request?
Hi!
I've posted a question on stackoverflow.com http://stackoverflow.com/questions/25424824/how-to-use-properties-of-an-item-in-a-collection-using-smartformat-net
Need your help with it.
Currently you accept any character into the {} string. So if we have code:
foreach (var key in collection)
{
//bla bla
}
If will destroy that block. At least make sure that there are no tabs/spaces/newlines in the block. You shouldn't have to escape the curly braces if the formatter can't use the block.
I found the following bug, which puts invalid "}" at the end:
class Program
{
public enum Gender
{
Unspecified = 0,
Male = 1,
Female = 2
}
static void Main(string[] args)
{
var result = "";
var template = "{gender:choose(Male|Female):{last_name:choose(null):Hi,|Dear Mr {last_name},}|{last_name:choose(null):Hi,|Dear Ms {last_name},}}";
var model1 = new
{
first_name = "Jane",
last_name = "Doe",
gender = Gender.Male
};
result = Smart.Format(template, model1);
Console.WriteLine(result);
var model2 = new
{
first_name = "Jane",
last_name = "Doe",
gender = Gender.Female
};
result = Smart.Format(template, model2);
Console.WriteLine(result);
Console.ReadLine();
}
}
I believe Smart.Format
should keep this behavior consistent with String.Format
. Please see below:
// Should throw a FormatException when token is not provided
Smart.Format("{0}, {1}", 0);
// like String.Format does
String.Format("{0}, {1}", 0);
// Same here, it should throw a FormatException
"{Name} {UndefinedToken}".FormatSmart(new { Name = "James" });
// Miss-spelled token is ignored
"{AltName}".FormatSmart(new { AlternativeName = "double zero seven" });
I get my users to compose their templates and when no proper error is available it makes it hard to find problems.
Thanks!
Im trying to generate an HTML mail code using format but im gettin an Invalid character in the selector error, this is the string because of the style section that uses {}, how can i handle this issue?
<title></title> <style type="text/css"> p.MsoNormal { margin-bottom: .0001pt; font-size: 12.0pt; font-family: "Times New Roman",serif; margin-left: 0cm; margin-right: 0cm; margin-top: 0cm; } table.MsoNormalTable {
font-size: 11.0pt;
font-family: "Calibri",sans-serif;
}
a:link {
font-family: "Verdana",sans-serif;
color: #FF6600;
text-decoration: none;
text-underline: none;
text-decoration: none;
text-line-through: none;
}
</style>
NUEVA SOLICITUD DE 2Ayuda
Solicitud:/o:p |
{id_Solicitud} |
Solicitante:/o:p |
{NomSolicita} |
Titulo:/o:p |
{NomSolicitud} |
Descripción:/o:p |
{DscSolicitud} |
/o:p |
|
Asignado a:/o:p |
{NomAsignado} |
/o:p |
Correo: {TxtCorreoAsignado}/o:p |
Estatus:/o:p |
{nomEstatus} ({dscEstatus})/o:p |
Fecha Alta:/o:p |
{fecAlta} |
Can you please add SNK to the dll in the nuget package?
Continuing discussion from issue #27. Below is the code to reproduce the issue:
void Main()
{
// unbalanced braces
var template1 = "[ {Name:name:|{0.Title:tilte:|name:} {Name:{}|{0.Title:{}|n/a} ]";
// balanced braces
var template2 = "[ {Name:name:|{0.Title:tilte:|name:}} {Name:{}|{0.Title:{}|n/a}} ]";
var info1 = new { Name = "A", Title = "" };
var info2 = new { Name = "", Title = "B" };
var info3 = new { Name = "", Title = "" };
Console.WriteLine(Smart.Format(template1, info1)); // [ name:
Console.WriteLine(Smart.Format(template1, info2)); // [ tilte: B ]
Console.WriteLine(Smart.Format(template1, info3)); // [ name: n/a ]
Console.WriteLine(Smart.Format(template2, info1)); // [ name:
Console.WriteLine(Smart.Format(template2, info2)); // [ tilte:
Console.WriteLine(Smart.Format(template2, info3)); // [ name:} n/a} ]
// Output I want is:
// [ name: A ]
// [ title: B ]
// [ name: n/a ]
}
You can run it in this fiddle.
Hi,
Item formats:
var result = Smart.Format("Timestamp is: {Timestamp:MMMM, yyyy}", data);
Conditional formatting:
var result = Smart.Format("Timestamp is: {Timestamp:{}|N/A}", data);
I understand how to achieve either one or the other but I cannot figure out how to combine them.
Hi,
I'm searching for a formatting library that is easy to read/write and can do exactly what yours can, at least it looks like that.
Some Questions:
{#for Items}{Name}{#forend}
Thanks for this library!!
Cheers!
Hi,
I think SmartFormat should support partial content so that you don't have to specify content within {} instead just supply the partial content id and then some where else define the partial content id with the content. For example, this is what you do currently
{IsHuman:I am a human|I am an alien}
but I think it will be more readable if we can do this instead
{IsHuman: {@HumanContent} | {@AlienContent} }
and then somewhere in the text you define these partial contents like
{@ HumanContent} blockquote>I am a human {/@ HumanContent } {@ AlienContent} I am an alien {/@ AlienContent}
The reason is I don't want to mix my html in smart format. (may be it is just me). Syntax could be anything but that's what I thought of.
class Base
{
public virtual int Prop1 { get; set; }
}
class Derived : Base
{
public override int Prop1
{
set { }
}
}
// usage code
Smart.Format("{Prop1}", new Derived { Prop1 = 10 }));
Unhandled Exception: SmartFormat.Core.Formatting.FormattingException: Error parsing format string: Could not evaluate the selector "Prop1" at 1 {Prop1}-^
Hi,
When I want to format a TimeSpan using default .NET formatting, SmartFormat ignores it and uses it's own human friendly format instead.
var time = new TimeSpan(1, 12, 24, 02);
Console.WriteLine(@"{0:hh\:mm\:ss}", time); // output: 12:24:02
Console.WriteLine(Smart.Format(@"{0:hh\:mm\:ss}", time)); // output: 1 day 12 hours 24 minutes 2 seconds
Is there any way to use default formatting for TimeSpans with SmartFormat?
Smart.Format("{N:Weight: {} lbs.|}", new { N = "20" })
Expected: "Weight: 20 lbs."
Result: (empty string)
Removing colon character works
Smart.Format("{N:Weight {} lbs.|}", new { N = "20" })
outputs "Weight 20 lbs."
Version: 1.6.1
I would be good if you signed this assembly. At least the one on NuGet
Best explained with example:
var a = Smart.Format("{SomeKey}", new Dictionary<string, object>() { { "SomeKey", 999 } });
Output: "999"
var b = Smart.Format("{Some.Key}", new Dictionary<string, object>(){ { "Some.Key", 999 } } );
Output: "", Expected Output: "999"
It seems the presence of .
, [
, or ]
cause the engine to check for a property within that path instead of trying to find an existing key. The best behavior would probably be for it to try both if a dictionary is keyed by strings.
To make matters slightly more complicated if I have a key of Count
, I get the Property value. It seems to me that in the presence of a dictionary that the existence of a key should be checked first.
var b = Smart.Format("{Count}", new Dictionary<string, object>(){ { "Count", 999 } } );
Output: "1", Expected Output: "999"
I need to format a string using 2 diferent sources like this:
Smart.Format(TEXT, Source1 (Class), Source 2 (Dictionary));
Your actual code processed only the first source, with this change i could process both
public bool TryEvaluateSelector(ISelectorInfo selectorInfo)
{
//NEW FOREACH ADDED
foreach (var current in selectorInfo.FormatDetails.OriginalArgs)
{
//REMOVED CODE
//var current = selectorInfo.CurrentValue;
var selector = selectorInfo.SelectorText;
// See if current is a IDictionary and contains the selector:
var rawDict = current as IDictionary;
if (rawDict != null)
{
foreach (DictionaryEntry entry in rawDict)
{
var key = (entry.Key as string) ?? entry.Key.ToString();
if (key.Equals(selector, selectorInfo.FormatDetails.Settings.GetCaseSensitivityComparison()))
{
selectorInfo.Result = entry.Value;
return true;
}
}
}
// this check is for dynamics and generic dictionaries
var dict = current as IDictionary<string, object>;
if (dict != null)
{
var val = dict.FirstOrDefault(x => x.Key.Equals(selector, selectorInfo.FormatDetails.Settings.GetCaseSensitivityComparison())).Value;
if (val != null)
{
selectorInfo.Result = val;
return true;
}
}
}
return false;
}
When we have a template such as: "{0: a | b }"
, it's not possible to tell which Extension will be used for formatting. If {0}
is a Number, then Pluralization formatter will be used, but all other types will use Conditional formatter. Likewise, "{0:abbr}"
will use the Time formatter if {0}
is a TimeSpan, but this makes the code hard to decipher.
Perhaps we should support explicitly named formatters? Examples to follow...
Hello, thank you for work on SmartFormat it is exactly what I was searching for my project.
Now I try to output a list of arrays of floats and get the value of the items in the array per index:
example:
{Object.ListOfArrays:{0} = first Item in Array, {1} = second Item in Array|; }
This is the data in C# notation:
var Object = new { ListOfArrays = new List() { {1,2}, {1.4,4.12} } };
And how I call Smart.Format:
Smart.Format( "{Object.ListOfArrays:{0} = first Item in Array, {1} = second Item in Array|; }", new{ Object=Object });
My expected output is:
1 = first Item in Array, 2 = second Item in Array; 1.4 = first Item in Array, 4.12 = second Item in Array
But instead of getting the items in the arrays back, SmartFormat outputs the first parameter on {0}
and nothing on {1}
as there is no second parameter. And I perfectly understand why this happens as {0}
refers to the first parameter on Smart.Format.
But my question is: Is there any way to access the elements of the arrays per index? Or is this type of nested templates only possible with named selectors like in your examples?
I hope it is understandable what my problem is and maybe someone can help me with this issue.
I'd really like to see a string builder version of SmartFormat!
Sure I can do something like
var builder = new StringBuilder();
builder.AppendLine("{Foo} {Bar}".FormatSmart(foobar))
But it would be awesome to have
var builder = new SmartFormatBuilder();
builder.AppendLine("{Foo} {Bar}", foobar);
The original code sample doesn't look so bad with one usage but image usage more along the lines of:
builder.AppendLine("{Foo} {Bar}".FormatSmart(foobar))
builder.AppendLine("{Foo} {Bar}".FormatSmart(foobar))
builder.AppendLine("{Foo} {Bar}".FormatSmart(foobar))
builder.AppendLine("{Foo} {Bar}".FormatSmart(foobar))
builder.AppendLine("{Foo} {Bar}".FormatSmart(foobar))
builder.AppendLine("{Foo} {Bar}".FormatSmart(foobar))
builder.AppendLine("{Foo} {Bar}".FormatSmart(foobar))
builder.AppendLine("{Foo} {Bar}".FormatSmart(foobar))
builder.AppendLine("{Foo} {Bar}".FormatSmart(foobar))
builder.AppendLine("{Foo} {Bar}".FormatSmart(foobar))
builder.AppendLine("{Foo} {Bar}".FormatSmart(foobar))
builder.AppendLine("{Foo} {Bar}".FormatSmart(foobar))
builder.AppendLine("{Foo} {Bar}".FormatSmart(foobar))
builder.AppendLine("{Foo} {Bar}".FormatSmart(foobar))
Now it's getting pretty obnoxious vs
builder.AppendLine("{Foo} {Bar}", foobar);
builder.AppendLine("{Foo} {Bar}", foobar);
builder.AppendLine("{Foo} {Bar}", foobar);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.