### Define a variable for examples
Source: https://github.com/axuno/smartformat/wiki/SubString _ SubStringFormatter
This C# variable is used across multiple examples to demonstrate string formatting.
```csharp
var person = new {Name = "Long John", City = "New York"};
```
--------------------------------
### Numeric Input Matching
Source: https://github.com/axuno/smartformat/wiki/Choose _ ChooseFormatter
Demonstrates how the choose formatter matches numeric inputs against a list of choices to produce a corresponding output. Includes examples for exact matches and a default output when no match is found.
```CSharp
Smart.Format("{0:choose(1|2|3):one|two|three|other}", 1);
// outputs: "one"
```
```CSharp
Smart.Format("{0:choose(1|2|3):one|two|three|other}", 9);
// outputs: "other"
```
```CSharp
Smart.Format("{0:choose(4.0|4.1|4.2):dot zero|dot one|dot two|other}", 4.1M);
// outputs: "dot one"
```
--------------------------------
### Sample HTML Content
Source: https://github.com/axuno/smartformat/wiki/HTML-with-CSS-or-JavaScript
This is an example of HTML content that includes embedded JavaScript and CSS, along with SmartFormat placeholders within the body.
```html
My name is {Name}. I'm living in {City}.
```
--------------------------------
### Localize String with Placeholders
Source: https://github.com/axuno/smartformat/wiki/Localization-_-LocalizationFormatter
Shows how localized strings can contain placeholders. The example localizes a string containing a numeric placeholder for both English and Spanish cultures.
```CSharp
Smart.Format("{0} {1:L(en):has {:#,#} inhabitants}", "X-City", 8900000);
```
```CSharp
Smart.Format("{0} {1:L(es):has {:#,#} inhabitants}", "X-City", 8900000);
```
--------------------------------
### DefaultFormatter Simple Invocation
Source: https://github.com/axuno/smartformat/wiki/Default _ DefaultFormatter
Demonstrates implicit and explicit invocation of the DefaultFormatter for basic number formatting. Includes an example with CultureInfo.
```CSharp
// implicit invokation
Smart.Format("{0}", 1234);
// explicit invokation by formatter name
Smart.Format("{0:d}", 1234);
// with CultureInfo
Smart.Format(CultureInfo.GetCultureInfo("en-US"), "{0:d}", 1234);
// all output: "1234"
```
--------------------------------
### Get Members from Base Classes with ReflectionSource
Source: https://github.com/axuno/smartformat/blob/main/CHANGES.md
ReflectionSource now includes members from base classes, providing more comprehensive data access.
```csharp
ReflectionSource now also gets members from base classes
```
--------------------------------
### Localize Nested Placeholders
Source: https://github.com/axuno/smartformat/wiki/Localization-_-LocalizationFormatter
Illustrates the support for nested placeholders within localized strings. The example shows how a placeholder within a localized string can itself be replaced and localized.
```CSharp
Smart.Format("{:L(fr):{ProductType}}");
```
--------------------------------
### Extract a substring by start index and length
Source: https://github.com/axuno/smartformat/wiki/SubString _ SubStringFormatter
Extracts a substring of a specified length starting from a given index. Requires the input to be a string.
```csharp
Smart.Format("{City:substr(0,3)}", person);
```
--------------------------------
### ListFormatter with Spacers and Placeholders
Source: https://github.com/axuno/smartformat/wiki/Lists _ ListFormatter
Example of using placeholders within the spacer and finalSpacer of the ListFormatter to dynamically control the output based on boolean conditions or other variables.
```CSharp
var args = new {
Names = new[] { "John", "Mary", "Amy" },
IsAnd = true, // true or false
Split = ", " // comma and space as list separator
};
_ = Smart.Format("{Names:list:{}\{Split}\{IsAnd:and|nor} }", args);
// Output for "IsAnd=true": "John, Mary and Amy"
// Output for "IsAnd=false": "John, Mary nor Amy"
```
--------------------------------
### Nesting Placeholders in SmartFormat
Source: https://github.com/axuno/smartformat/wiki/Placeholders-and-Nesting
Demonstrates how to use nesting in SmartFormat to avoid repetition when accessing deeply nested properties. The example shows accessing City and FirstName from a nested Person object.
```CSharp
var person = new
{
Person = new
{
FirstName = "John",
LastName = "Long",
Address = new { City = "London", Street = "Main St" }
}
};
Smart.Format("City: {Person:{Address:{City}}, Name: {FirstName}}", person);
```
--------------------------------
### Instantiate SmartFormatter with Settings
Source: https://github.com/axuno/smartformat/wiki/Configuration
Demonstrates the correct way to instantiate SmartFormatter with custom settings. Settings should be provided during instantiation and not modified afterward.
```Csharp
// DO
var sf = new SmartFormatter(new SmartSettings { CaseSensitivity = CaseSensitivityType.CaseInsensitive });
// DO NOT
var sf = new SmartFormatter();
sf.Settings.CaseSensitivity = CaseSensitivityType.CaseInsensitive;
```
--------------------------------
### Use Registered Templates for Formatting
Source: https://github.com/axuno/smartformat/wiki/Templates-_-TemplateFormatter
Demonstrates using registered templates with Smart.Format. It shows how to apply different templates based on arguments.
```Csharp
var person = new
{
FirstName = "Joseph",
Nickname = "Joe",
LastName = "Doe"
};
// Use the "master" template with different args
// Informal
Smart.Format("{0:t(salutation)}:", person, false);
// Outputs "Hi Joe:"
// Formal
Smart.Format("{0:t(salutation)}:", person, true);
// Outputs "Dear Mr Doe:"
```
--------------------------------
### Extract a substring by start index
Source: https://github.com/axuno/smartformat/wiki/SubString _ SubStringFormatter
Extracts a substring starting from a specified index to the end of the string. Requires the input to be a string.
```csharp
Smart.Format("{Name:substr(5)}", person);
```
--------------------------------
### Using a FormatDelegate
Source: https://github.com/axuno/smartformat/wiki/Default _ DefaultFormatter
Illustrates formatting using a `FormatDelegate`, which allows custom formatting logic for indexed placeholders. Requires the `SmartFormat.Utilities` namespace.
```CSharp
var amount = 123.456M;
var c = new System.Globalization.CultureInfo("fr-FR");
// Only works for indexed placeholders
var formatDelegate = new SmartFormat.Utilities.FormatDelegate((format, culture) => $"{format}: {amount.ToString(c)}");
Smart.Format("{0:The amount is}", formatDelegate);
// Outputs: "The amount is: 123,456"
```
--------------------------------
### Basic Smart.Format Usage
Source: https://github.com/axuno/smartformat/wiki/Syntax,-Terminology
Demonstrates basic string formatting with Smart.Format using positional arguments and anonymous objects.
```Csharp
using SmartFormat;
Smart.Format("{0} {1}", "Hello", "World")
// outputs "Hello World"
Smart.Format("{h} {w}", new{ h = "Hello", w = "World" })
// outputs "Hello World"
```
--------------------------------
### Create Default SmartFormat
Source: https://github.com/axuno/smartformat/wiki/Templates-_-TemplateFormatter
Initializes the default SmartFormat instance. This is the first step before adding extensions.
```Csharp
var formatter = Smart.CreateDefaultSmartFormat();
```
--------------------------------
### Smart.Format with Alignment and Item Format
Source: https://github.com/axuno/smartformat/wiki/Syntax,-Terminology
Demonstrates using alignment and item formatting to control padding and number representation.
```Csharp
var data = new { Item = 9 };
Smart.Format("There are {Item,7:default:000} items", data);
// Outputs: "There are 009 items"
```
--------------------------------
### Output Only If Null
Source: https://github.com/axuno/smartformat/wiki/Null-_-NullFormatter
Use the NullFormatter to display a specific string only when the formatted value is null. This example shows formatting a null object.
```CSharp
Smart.Format("{0:isnull:N/A}", default(object));
// outputs: "N/A"
```
--------------------------------
### Using a Custom Localization Provider
Source: https://github.com/axuno/smartformat/wiki/Localization-_-LocalizationFormatter
Demonstrates how to configure SmartFormat to use a custom `ILocalizationProvider` and add the `LocalizationFormatter`. This allows for localized output using the custom provider.
```CSharp
// Change settings for your provider
Smart.Default.Settings.Localization.LocalizationProvider = new DictLocalizationProvider();
// Add the formatter
Smart.Default.AddExtensions(new LocalizationFormatter());
Smart.Format("{:L(en):COUNTRY} * {:L(fr):COUNTRY} * {:L(es):COUNTRY}");
```
--------------------------------
### Specify Options for Named Formatters
Source: https://github.com/axuno/smartformat/blob/main/CHANGES.md
Enables passing options to a named formatter, providing more control over formatting. Example: '{0:name(options): ___ }'.
```csharp
{0:name(options): ___ }
```
--------------------------------
### Basic SmartFormat Usage
Source: https://github.com/axuno/smartformat/wiki/Home
Demonstrates the basic usage of SmartFormat for string interpolation with named placeholders. Requires the SmartFormat library.
```C#
var data = new { Library = "SmartFormat"};
_ = Smart.Format("Composed with {Library}.", data);
// Result: "Composed with SmartFormat."
```
--------------------------------
### String Input Matching (null, empty, value)
Source: https://github.com/axuno/smartformat/wiki/Choose _ ChooseFormatter
Shows how the choose formatter handles string inputs, including null, empty strings, and other string values. It maps them to predefined outputs.
```CSharp
Smart.Format("{0:choose(null|):null|empty|{}}", default(string?))
// outputs: "null"
```
```CSharp
Smart.Format("{0:choose(null|):null|empty|{}}", "")
// outputs: "empty"
```
```CSharp
Smart.Format("{0:choose(null|):null|empty|{}}", "something else")
// "something else"
```
--------------------------------
### Use Named Formatters in SmartFormat.NET
Source: https://github.com/axuno/smartformat/blob/main/CHANGES.md
Allows specifying a formatter by its name for targeted formatting. For example, '{0:plural: ___ }' uses the Plural formatter.
```csharp
{0:plural: ___ }
```
```csharp
{0:default: ___ }
```
--------------------------------
### SmartFormat Localization with StringFormatCompatibility
Source: https://github.com/axuno/smartformat/wiki/string.Format Compatibility
Demonstrates localization in SmartFormat by providing a CultureInfo object. This allows formatting numbers and dates according to specific cultural conventions, mirroring string.Format behavior.
```Csharp
Smart.Format(CultureInfo.GetCultureInfo("en-US"), "{0:C}", 1234)
// Outputs: "$1,234.00"
Smart.Format(CultureInfo.GetCultureInfo("ja-JP"), "{0:C}", 1234)
// Outputs: "1234"
```
--------------------------------
### Registering Data Sources
Source: https://github.com/axuno/smartformat/wiki/Data Source Extensions
Demonstrates how to register source extensions with the SmartFormatter using AddExtensions and InsertExtension.
```APIDOC
## Register Data Sources
Required `ISource` extensions must be registered with the `SmartFormatter`.
Data sources are added by calling
* `SmartFormatter.AddExtensions(...)`
* `SmartFormatter.InsertExtension(...)`
With `AddExtensions(...)` all `WellKnownExtensionTypes.Sources` and `WellKnownExtensionTypes.Formatters` are *automatically* inserted to the extension list at the place *where they usually should be*.
`InsertExtension(...)` lets you insert an extension to the desired position in the list.
From a performance perspective, only register source extensions that are actually needed:
```CSharp
// Add needed source extensions
var smart = new SmartFormatter()
.AddExtensions(new ReflectionSource(), new DefaultSource());
// Add all default source extensions (and formatters)
smart = Smart.CreateDefaultFormatter();
```
```
--------------------------------
### Handle Multiple Elements with Same Name using XElementFormatter
Source: https://github.com/axuno/smartformat/wiki/XML _ XElementFormatter
XElementFormatter treats multiple elements with the same name as a list, enabling formatting with ConditionalFormatter or ListFormatter. This example demonstrates counting elements and listing them.
```CSharp
var multiFirstName = XElement.Parse(
"" +
"Joe" +
"Jack" +
"Doe" +
"Jim" +
"");
var smart = Smart.CreateDefaultSmartFormat()
.AddExtensions(new XElementFormatter())
.AddExtensions(new XmlSource());
// More xml elements with the same name are treated as a list
// (used together with ConditionalFormatter)
smart.Format("There {FirstName.Count:cond:is {} Doe |are {} Does}", multiFirstName);
// Outputs: "There are 3 Does"
// List FirstNames with ListFormatter
smart.Format("{FirstName:list:|, | and }", multiFirstName);
// Outputs: "Joe, Jack and Jim"
```
--------------------------------
### Registering Source Extensions - SmartFormatter
Source: https://github.com/axuno/smartformat/wiki/Data Source Extensions
Demonstrates how to add needed source extensions to SmartFormatter. Use AddExtensions for specific sources or Smart.CreateDefaultFormatter() to include all default sources and formatters.
```CSharp
// Add needed source extensions
var smart = new SmartFormatter()
.AddExtensions(new ReflectionSource(), new DefaultSource());
// Add all default source extensions (and formatters)
smart = Smart.CreateDefaultFormatter();
```
--------------------------------
### Smart.Format with Selector Case Conversion
Source: https://github.com/axuno/smartformat/wiki/Syntax,-Terminology
Shows how to use selectors with methods like ToUpper and ToLower for case conversion within the format string.
```Csharp
// More than 1 selector
Smart.Format("{0.ToUpper} {1.ToLower}", "Hello", "World")
// outputs "HELLO world"
```
--------------------------------
### Boolean Input Matching
Source: https://github.com/axuno/smartformat/wiki/Choose _ ChooseFormatter
Shows how to use the choose formatter with boolean inputs. Both 'True'/'False' and 'true'/'false' casing are accepted for matching.
```CSharp
Smart.Format("{0:choose(True|False):yes|no}", true);
```
```CSharp
Smart.Format("{0:choose(true|false):yes|no}", true);
// both output: "yes"
```
--------------------------------
### Access Outer Scopes with Nested Scopes Feature
Source: https://github.com/axuno/smartformat/blob/main/CHANGES.md
Enables nested templates to access outer scopes without workarounds. For example, in '{Person: {Address: {City} {FirstName} } }', '{City}' comes from 'Address' and '{FirstName}' from 'Person'.
```csharp
{Person: {Address: {City} {FirstName} } }
```
--------------------------------
### Compile-time Character Literal Conversion in C# and Smart.Format
Source: https://github.com/axuno/smartformat/wiki/Character-Literals-in-Format-Strings
When format strings originate from code, C# and Smart.Format automatically convert character literals to their Unicode representations. This example shows the TAB character being correctly interpreted by both `string.Format` and `Smart.Format`.
```Csharp
string.Format("\t")
Smart.Format("\t")
// resulting character in both cases: TAB
```
--------------------------------
### FormatSmart for string
Source: https://github.com/axuno/smartformat/wiki/Extension-Methods
Use string.FormatSmart for direct string formatting. Ensure SmartExtensions are imported.
```CSharp
string.FormatSmart("template", args...);
```
--------------------------------
### Configure PersistentVariablesSource
Source: https://github.com/axuno/smartformat/wiki/Data Source Extensions
Demonstrates how to set up and use PersistentVariablesSource to manage global variables for SmartFormatter. This involves creating VariablesGroup and Variable instances, adding them to the source, and registering the source with the SmartFormatter.
```CSharp
// The top container
// It gets its name later, when being added to the PersistentVariablesSource
var varGroup = new VariablesGroup();
// Add a (nested) VariablesGroup named 'group' to the top container
varGroup.Add("group", new VariablesGroup
{
// Add variables to the group
{ "groupString", new StringVariable("groupStringValue") },
{ "groupDateTime", new Variable(new DateTime(2024, 12, 31)) }
});
// Add more variables to the container
varGroup.Add("topInteger", new IntVariable(12345));
varGroup.Add("topString", new StringVariable("topStringValue"));
// The formatter for persistent variables requires only 2 extensions
var smart = new SmartFormatter();
smart.FormatterExtensions.Add(new DefaultFormatter());
var pvs = new PersistentVariablesSource
{
// Here, the top container gets its name
{ "global", varGroup }
};
// Best to put it to the top of source extensions
smart.AddExtensions(0, pvs);
// Note: We don't need args to the formatter for PersistentVariablesSource variables
_ = smart.Format(CultureInfo.InvariantCulture,
"{global.group.groupString} {global.group.groupDateTime:'groupDateTime='yyyy-MM-dd}");
// result: "groupStringValue groupDateTime=2024-12-31"
_ = smart.Format("{global.topInteger}");
// result: "12345"
_ = smart.Format("{global.topString}");
// result: "topStringValue"
```
--------------------------------
### Conditional Formatting with ValueTuple
Source: https://github.com/axuno/smartformat/wiki/Data Source Extensions
Apply conditional logic within the format string to control output based on variable values. This example shows how to conditionally display 'ItemString' based on 'ItemInt' and 'ItemBool' values, keeping business logic out of the format string.
```CSharp
Smart.Format("{Show:cond:{ItemString}|Don't show}",
(data3, new { Show = data1.ItemInt == 123 && data2.ItemBool }));
// Output: "an item"
```
--------------------------------
### How Data Sources Work
Source: https://github.com/axuno/smartformat/wiki/Data Source Extensions
Explains the process of how SmartFormatter evaluates selectors and invokes registered ISources and IFormatters.
```APIDOC
## How do Data Sources Work
The `SmartFormatter` evaluates the selectors in a `Placeholder` one by one. Fore each selector, the registered `ISource`s are invoked. As soon as an `ISource` can detect a matching variable from the data arguments, it returns the value.
That's why the order in the list of registered data sources is important.
If no matching data can be found for a `Placeholder` across all `ISource`s, a `FormattingException` will throw.
After the selector was successfully evaluated, `IFormatter`(s) will be invoked.
For `SmartSettings.CaseSensitivity == CaseSensitivityType.CaseInsensitive`, and multiple members share the same name but differ in case, the first encountered member will be selected.
```
--------------------------------
### Format String Without Nullable Notation
Source: https://github.com/axuno/smartformat/wiki/Syntax,-Terminology
When using SmartFormat, attempting to access members or methods on a potentially null object without explicit nullable notation in the format string will result in a FormattingException. This example shows the behavior when 'Name.ToUpper' is called on a null 'Name' property.
```Csharp
Smart.Format("Name: {Name.ToUpper} - Birthday: {Birthday.Date:yyyy-MM-dd}", data);
// Throws a FormattingException
// Name: {Name.ToUpper}
// ------------^
```
--------------------------------
### Smart.Format with Pluralization Formatter Options
Source: https://github.com/axuno/smartformat/wiki/Syntax,-Terminology
Illustrates using the PluralLocalizationFormatter with options to handle pluralization based on language.
```Csharp
Smart.Format("{0:plural(en):zero|one|many}", 1);
// outputs "one" for the English language option
```
--------------------------------
### Accessing List Elements in Smart.Format
Source: https://github.com/axuno/smartformat/wiki/Syntax,-Terminology
Shows how to access elements within a list using index notation, either with square brackets or dot notation.
```Csharp
var data = new {Numbers = new List{0,1,2,3}};
Smart.Format("{Numbers[1]}", data);
Smart.Format("{Numbers.1}", data);
// both output "1"
```
--------------------------------
### Import AngleSharp Library
Source: https://github.com/axuno/smartformat/wiki/HTML-with-CSS-or-JavaScript
Include this using statement to leverage AngleSharp for HTML parsing.
```csharp
using AngleSharp;
```
--------------------------------
### Configure Extensions with GetFormatterExtension and GetSourceExtension
Source: https://github.com/axuno/smartformat/blob/main/CHANGES.md
Provides methods to retrieve and configure formatter and source extensions for custom SmartFormatter behavior.
```csharp
```SmartFormatter.GetFormatterExtension``` and ```GetSourceExtension``` methods, which can be used to configure extensions
```
--------------------------------
### SmartFormat Alignment with StringFormatCompatibility
Source: https://github.com/axuno/smartformat/wiki/string.Format Compatibility
Illustrates how to use alignment specifiers for left and right justification within a specified width in SmartFormat, similar to string.Format.
```Csharp
Smart.Format("|{0,-10}|{1,10}|", "Left", "Right");
// Outputs: "|Left | Right|"
```
--------------------------------
### SmartFormat vs. string.Format
Source: https://github.com/axuno/smartformat/wiki/Home
Compares SmartFormat with the built-in string.Format for identical formatting tasks. Useful for migrating or understanding compatibility.
```C#
var stringFormat = string.Format("{0} {0:N2} {1:yyyy-MM-dd}", 5, new DateTime(1900, 12, 31));
var smartFormat = Smart.Format("{0} {0:N2} {1:yyyy-MM-dd}", 5, new DateTime(1900, 12, 31));
// Result: (stringFormat == smartFormat) == true
```
--------------------------------
### Smart.Format with Nullable Notation - Basic Usage
Source: https://github.com/axuno/smartformat/wiki/Syntax,-Terminology
Demonstrates using nullable notation (?. ) to safely access properties that might be null, outputting an empty string by default.
```Csharp
var data = new Person { Name = "Joe", Birthday = new DateTime(2000, 6, 30) };
Smart.Format("Name: {Name?.ToUpper} - Birthday: {Birthday?.Date:yyyy-MM-dd}", data);
// Outputs: "Name: JOE - Birthday: 2000-06-30"
data = new Person { Name = null, Birthday = null };
Smart.Format("Name: {Name?.ToUpper} - Birthday: {Birthday?.Date:yyyy-MM-dd}", data);
// Outputs: "Name: - Birthday:"
```
--------------------------------
### Enum Input Matching
Source: https://github.com/axuno/smartformat/wiki/Choose _ ChooseFormatter
Illustrates matching enum values using the choose formatter. The formatter correctly maps enum members to their specified outputs.
```CSharp
enum Gender { Female, Male, Unknown };
Smart.Format("{0:choose(Male|Female):his|her|their}", Gender.Female);
// outputs: "her"
```
```CSharp
Smart.Format("{0:choose(Male|Female):his|her|their}", Gender.None);
// outputs: "their"
```
--------------------------------
### Register Default Formatters in C#
Source: https://github.com/axuno/smartformat/wiki/How-Formatters-Work
Demonstrates how to add source and formatter extensions to a SmartFormatter instance. Use this to manually register specific formatters or use Smart.CreateDefaultFormatter() to include all default extensions.
```csharp
// Add needed source extensions
var smart = new SmartFormatter()
// Add source extensions
.AddExtensions(new ReflectionSource(), new DefaultSource())
// Add formatter extensions
.AddExtensions(new ListFormatter(), new DefaultFormatter);
// Add all default source and formatter extensions
smart = Smart.CreateDefaultFormatter();
```
--------------------------------
### Using Expressions in SmartFormat Placeholders
Source: https://github.com/axuno/smartformat/wiki/Placeholders-and-Nesting
Shows how SmartFormat supports expressions, such as calling parameterless methods like ToUpper and ToLower, within named placeholders.
```CSharp
Smart.Format("{FirstName.ToUpper} {LastName.ToLower}", person)
```
--------------------------------
### Format with KeyValuePair
Source: https://github.com/axuno/smartformat/wiki/Data Source Extensions
Use KeyValuePairSource for simple, performant named placeholders. The type arguments for KeyValuePair must be .
```csharp
Smart.Format("{placeholder}", new KeyValuePair("placeholder", "some value")
```
--------------------------------
### Register and Use Custom Formatter
Source: https://github.com/axuno/smartformat/wiki/Creating-Your-Own-Extension
Register the custom formatter using AddExtensions and invoke it within a format string. Ensure the formatter is added before attempting to use it in Smart.Format.
```CSharp
Smart.Default.AddExtensions(new HelloFormatter());
Smart.Format("{value:hello(world):earth}", new { value = true });
// Outputs: "HELLO world"
Smart.Format("{value:hello(world):earth}", new { value = false });
// Outputs: "HELLO earth"
```
--------------------------------
### SmartFormat Extensions with ListFormatter
Source: https://github.com/axuno/smartformat/wiki/string.Format Compatibility
Demonstrates the use of SmartFormat extensions, such as the ListFormatter, when StringFormatCompatibility is disabled. This allows for advanced formatting of collections.
```Csharp
var data = new [] {1, 2, 3};
_ = Smart.Format(@"{0:list:*{:N2}*| \: }", data);
// Result: "*1,00* : *2,00* : *3,00*"
```
--------------------------------
### Custom ILocalizationProvider Implementation
Source: https://github.com/axuno/smartformat/wiki/Localization-_-LocalizationFormatter
Provides a C# implementation of a custom `ILocalizationProvider` using a dictionary to store translations. This allows for flexible localization beyond standard resource files.
```CSharp
public class DictLocalizationProvider : ILocalizationProvider
{
private readonly Dictionary> _translations;
public DictLocalizationProvider()
{
_translations = new Dictionary> {
{ "en", new Dictionary { { "COUNTRY", "country" } } },
{ "fr", new Dictionary { { "COUNTRY", "pays" } } },
{ "es", new Dictionary { { "COUNTRY", "país" } } }
};
}
public string? GetString(string name)
{
return GetTranslation(name, CultureInfo.CurrentUICulture.TwoLetterISOLanguageName);
}
public string? GetString(string name, string cultureName)
{
return GetTranslation(name, cultureName);
}
public string? GetString(string name, CultureInfo cultureInfo)
{
return GetTranslation(name, cultureInfo.TwoLetterISOLanguageName);
}
private string? GetTranslation(string name, string cultureName)
{
if (!_translations.TryGetValue(cultureName, out var entry)) return null;
return entry.TryGetValue(name, out var localized) ? localized : null;
}
}
```
--------------------------------
### Argument Implementing IFormattable
Source: https://github.com/axuno/smartformat/wiki/Default _ DefaultFormatter
Shows how to format custom objects that implement the `IFormattable` interface. The `ToString` method is used with a provided format string.
```CSharp
// A simple class
public class FmtDemo : IFormattable
{
public string ToString(string? format, IFormatProvider? p)
{
return $"{format} implmenting IFormattable";
}
}
Smart.Format("{0:FmtDemo}", new FmtDemo());
// Outputs: "FmtDemo implementing IFormattable"
```
--------------------------------
### Customizing Split Character and Case Sensitivity
Source: https://github.com/axuno/smartformat/wiki/Choose _ ChooseFormatter
Shows how to change the default split character from '|' to ',' and set case sensitivity for the choose formatter. This allows more flexible formatting options.
```CSharp
var chooseFmt = Smart.Default.GetFormatterExtension()!;
chooseFmt.SplitChar = ',';
chooseFmt.CaseSensitivity = CaseSensitivityType.CaseInsensitive;
Smart.Format("{0:choose(one,two,three):|1|,|2|,|3|,|??|}", "TWO");
// outputs: "|2|"
```
--------------------------------
### Formatting an IList with SmartFormat
Source: https://github.com/axuno/smartformat/wiki/Home
Shows how to format an IList using SmartFormat's list formatting capabilities. Specify custom delimiters and suffixes.
```C#
var data = new [] {1, 2, 3, 4, 5};
_ = Smart.Format("{0:list:N2|, |, and }.", (object) data);
// Result: "1.00, 2.00, 3.00, 4.00, and 5.00."
```
--------------------------------
### ReflectionSource - Accessing Object Members
Source: https://github.com/axuno/smartformat/wiki/Data Source Extensions
Demonstrates using ReflectionSource to access object members like properties, fields, and parameterless methods. Caching is enabled by default for performance.
```CSharp
Smart.Format("{Item}", new { Item = 999 });
```
--------------------------------
### Format with SystemTextJsonSource
Source: https://github.com/axuno/smartformat/wiki/Data Source Extensions
Use SystemTextJsonSource to format strings by accessing child elements of JElement. Requires the SmartFormat.Extensions.System.Text.Json NuGet package.
```csharp
Smart.Format("{Name}", JsonDocument.Parse("{ \"Name\":\"John\"}").RootElement)
```
--------------------------------
### ListFormatter - Formatting Lists
Source: https://github.com/axuno/smartformat/wiki/Data Source Extensions
Shows how to use ListFormatter to format collections like lists. It allows specifying custom separators and conjunctions for the list elements.
```CSharp
Smart.Format("{0:list:{}|, and }", new List { "one", "two", "three" });
// Outputs: "one, two, and three"
```
--------------------------------
### SmartFormat Item Formatting with StringFormatCompatibility
Source: https://github.com/axuno/smartformat/wiki/string.Format Compatibility
Shows how to format items like numbers and dates using SmartFormat with string.Format compatibility enabled. Custom format specifiers like 'N3' and 'MMMM, yyyy' are supported.
```Csharp
Smart.Format("{0:N3} | {1:MMMM, yyyy}", 5.5, new DateTime(2010,3,4));
// Outputs: "5.500 | March, 2010"
```
--------------------------------
### SmartFormat Indexed Placeholders with StringFormatCompatibility
Source: https://github.com/axuno/smartformat/wiki/string.Format Compatibility
Explains the use of indexed placeholders in SmartFormat, where numbers correspond to the argument index, identical to string.Format.
```Csharp
Smart.Format("{0} {1}", "Hello", "World");
// Outputs: "Hello World"
```
--------------------------------
### Culture-Aware Formatting with SmartFormat
Source: https://github.com/axuno/smartformat/wiki/Common-Pitfalls
Use Smart.Format with a CultureInfo object to ensure proper formatting of numbers, dates, and currency according to specific regional standards.
```CSharp
Smart.Format(new CultureInfo("en-US"), "{0:C}", 1234)
```
--------------------------------
### WriteSmart for TextWriter (Console)
Source: https://github.com/axuno/smartformat/wiki/Extension-Methods
Use WriteSmart with Console.Out to format strings directly to the console. Ensure SmartExtensions are imported.
```CSharp
Console.Out.WriteSmart("template", args...);
```
--------------------------------
### Null Input Matching
Source: https://github.com/axuno/smartformat/wiki/Choose _ ChooseFormatter
Demonstrates matching null values with the choose formatter. The formatter handles 'null' and 'NULL' case-insensitively.
```CSharp
Smart.Format("{0:choose(null): N/A|{}}", default(object));
```
```CSharp
Smart.Format("{0:choose(NULL): N/A|{}}", default(object));
// both outputs: "N/A"
```
--------------------------------
### Register a Simple Template
Source: https://github.com/axuno/smartformat/wiki/Templates-_-TemplateFormatter
Registers a template with a given name and content. The content can include placeholders like {variable}.
```Csharp
templates.Register("SomeTemplate", "The template content: {variable}");
```
--------------------------------
### Nested Placeholder in Output
Source: https://github.com/axuno/smartformat/wiki/Choose _ ChooseFormatter
Illustrates using nested placeholders within the output of the choose formatter. This allows dynamic content generation based on the matched choice.
```CSharp
Smart.Format("{0:choose(null): N/A|{}}", 1234);
// outputs: "1234"
```
--------------------------------
### Format with String Methods
Source: https://github.com/axuno/smartformat/wiki/Data Source Extensions
Utilize StringSource to apply built-in string manipulation methods like ToUpper, Trim, and ToBase64 during formatting.
```csharp
Smart.Format("{0.ToUpper}", "lower")
```
```csharp
Smart.Format("{0.Length}", "A name")
```
```csharp
Smart.Format("{0.ToUpper}", "dış")
```
```csharp
Smart.Format("{0.ToUpperInvariant}", "dış")
```
```csharp
Smart.Format("{0.ToLower}", "DIŞ")
```
```csharp
Smart.Format("{0.ToLowerInvariant}", "DIŞ")
```
```csharp
Smart.Format("{0.TrimStart}", " abc")
```
```csharp
Smart.Format("{0.TrimEnd}", "abc ")
```
```csharp
Smart.Format("{0.Trim}", " abc ")
```
```csharp
Smart.Format("{0.Capitalize}", "word")
```
```csharp
Smart.Format("{0.CapitalizeWords}", "john DOE")
```
```csharp
Smart.Format("{0.ToBase64}", "xyz")
```
```csharp
Smart.Format("{0.FromBase64}", "eHl6")
```
```csharp
Smart.Format("{0.ToCharArray}", "abc")
```
--------------------------------
### Combine Localization with Pluralization
Source: https://github.com/axuno/smartformat/wiki/Localization-_-LocalizationFormatter
Demonstrates using the LocalizationFormatter in conjunction with the pluralization formatter. This allows for culture-specific pluralization of localized strings.
```CSharp
Smart.Format("{0:plural:{:L(en):{} item}|{:L(en):{} items}}", 0);
```
```CSharp
Smart.Format("{0:plural:{:L(fr):{} item}|{:L(fr):{} items}}", 0);
```
```CSharp
Smart.Format("{0:plural:{:L(fr):{} item}|{:L(fr):{} items}}", 200);
```
--------------------------------
### Format with XmlSource
Source: https://github.com/axuno/smartformat/wiki/Data Source Extensions
Use XmlSource to format strings by accessing child elements of an XElement. Requires the SmartFormat.Extensions.Xml NuGet package.
```csharp
Smart.Format("{Name}", XElement.Parse("Joe"));
```
--------------------------------
### Format TimeSpan with TimeFormatter
Source: https://github.com/axuno/smartformat/wiki/TimeSpan-_-TimeFormatter
Demonstrates various formatting options for TimeSpan objects using the TimeFormatter. Ensure the TimeFormatter extension is registered before use.
```CSharp
var args = new object[] {
TimeSpan.Zero,
new TimeSpan(1,1,1,1,1),
new TimeSpan(0,2,0,2,0),
new TimeSpan(3,0,0,3,0),
new TimeSpan(0,0,0,0,4),
new TimeSpan(5,0,0,0,0)
};
// Register the TimeFormatter extension
Smart.Default.AddExtensions(new TimeFormatter());
Smart.Format("{0:time(en):noless}", args);
// Outputs: "0 seconds"
Smart.Format("{1:time(en):hours}", args);
// Outputs: "25 hours"
Smart.Format("{1:time(en):hours minutes}", args);
// Outputs: "25 hours 1 minute"
Smart.Format("{2:time(en):days milliseconds}", args);
// Outputs: "2 hours 2 seconds"
Smart.Format("{2:time(en):days milliseconds auto}", args);
// Outputs: "2 hours 2 seconds"
Smart.Format("{2:time(en):days milliseconds short}", args);
// Outputs: "2 hours"
Smart.Format("{2:time(en):days milliseconds fill}", args);
// Outputs: "2 hours 0 minutes 2 seconds 0 milliseconds"
Smart.Format("{2:time(en):days milliseconds full}", args);
// Outputs: "0 days 2 hours 0 minutes 2 seconds 0 milliseconds"
Smart.Format("{3:time(en):abbr}", args);
// Outputs: "3d 3s"
```
--------------------------------
### Implement IFormatter for Custom Formatting
Source: https://github.com/axuno/smartformat/wiki/Creating-Your-Own-Extension
Create a class implementing IFormatter to define custom logic for evaluating formats. The TryEvaluateFormat method determines if the formatter can handle the input and performs the output writing.
```CSharp
public class HelloFormatter : IFormatter
{
public string Name { get; set; } = "hello";
public bool CanAutoDetect { get; set; } = true;
public bool TryEvaluateFormat(IFormattingInfo formattingInfo)
{
var iCanHandleThisInput = formattingInfo.CurrentValue is bool;
if (!iCanHandleThisInput)
return false;
formattingInfo.Write("HELLO ");
if ((bool) formattingInfo.CurrentValue)
formattingInfo.Write(formattingInfo.FormatterOptions);
else
formattingInfo.Write(formattingInfo.Format.GetLiteralText());
return true;
}
}
```
--------------------------------
### List Matching Regex Group Values with IsMatch
Source: https://github.com/axuno/smartformat/wiki/RegEx _ IsMatchFormatter
Shows how to use the 'm' placeholder (configurable via PlaceholderNameForMatches) to list all captured regex group values when IsMatchFormatter is successful. The 'm' placeholder provides access to the GroupCollection.
```CSharp
KeyValuePair arg = new("theValue", "Some123Content");
Smart.Format("{theValue:ismatch(^.+\(1\)\(2\)\(3\).+$):Matches for '{}'\\: {m:list:| - }|No match}", arg);
// Outputs: "Matches for 'Some123Content': Some123Content - 1 - 2 - 3"
```
--------------------------------
### Use Alternative Braces for Templates
Source: https://github.com/axuno/smartformat/blob/main/CHANGES.md
Allows templates to utilize alternative characters for braces, providing flexibility in format string design.
```csharp
```UseAlternativeBraces``` method, so that templates can use alternative characters
```
--------------------------------
### Format String with Multiple Objects
Source: https://github.com/axuno/smartformat/wiki/Data Source Extensions
Use indexed arguments to reference properties from different objects passed as separate arguments to Smart.Format.
```CSharp
var data1 = new { ItemInt = 123 };
var data2 = new { ItemBool = true };
var data3 = new { ItemString = "an item" };
Smart.Format("{0.ItemInt} * {1.ItemBool} * {2.ItemString}", data1, data2, data3 );
// Outputs: "123 * True * an item"
```
--------------------------------
### Indexed Placeholders with string.Format and SmartFormat
Source: https://github.com/axuno/smartformat/wiki/Placeholders-and-Nesting
Compares the use of indexed placeholders in C#'s string.Format and SmartFormat. Both achieve the same result by referencing arguments by their position.
```CSharp
string.Format("{0} {1}", person.FirstName, person.LastName)
```
```CSharp
Smart.Format("{0} {1}", person.FirstName, person.LastName)
```
--------------------------------
### Conditional Output with Gender Formatting
Source: https://github.com/axuno/smartformat/wiki/Home
Illustrates using SmartFormat's 'choose' formatter for conditional output based on a value, commonly used for gendered pronouns.
```C#
var data = new[] { new { Name = "John", Gender = 0 },
new { Name = "Mary", Gender = 1 } };
_ = Smart.Format("{Name} commented on {Gender:choose:his|her} photo", data[1]);
// Result: "Mary commented on her photo"
```
--------------------------------
### Localize Literal to Spanish
Source: https://github.com/axuno/smartformat/wiki/Localization-_-LocalizationFormatter
Demonstrates how to localize a literal string to Spanish using the LocalizationFormatter. The culture can be specified directly in the format string or passed as an argument.
```CSharp
Smart.Format("{:L(es):WeTranslateText}");
```
```CSharp
var culture = CultureInfo.GetCultureInfo("es");
Smart.Format(culture, "{:L:WeTranslateText}");
```
--------------------------------
### Recommended TimeFormatter Format (v3+)
Source: https://github.com/axuno/smartformat/blob/main/CHANGES.md
This format string is recommended for SmartFormat v3 and later. It allows for including the language as an option to the TimeFormatter.
```csharp
// Without language option:
var formatRecommended = "{0:time:abbr hours noless:}";
// With language option:
var formatRecommended = "{0:time(en):abbr hours noless:}";
```
--------------------------------
### Smart.Format with Nullable Notation and IsNullFormatter
Source: https://github.com/axuno/smartformat/wiki/Syntax,-Terminology
Shows how to use the IsNullFormatter with nullable notation to provide default values when properties are null.
```Csharp
// Or nicer by using the IsNullFormatter:
Smart.Format("Name: {Name?.ToUpper:isnull:n/a|{}} - Birthday: {Birthday?.Date:isnull:n/a|{:yyyy-MM-dd}}", data)
// Outputs: "Name: n/a - Birthday: n/a"
```
--------------------------------
### Named Placeholders in SmartFormat
Source: https://github.com/axuno/smartformat/wiki/Placeholders-and-Nesting
Demonstrates using named placeholders in SmartFormat, which allows referencing object properties directly by their names instead of their index.
```CSharp
Smart.Format("{FirstName} {LastName}", person)
```
--------------------------------
### Parse HTML and Format with SmartFormat using AngleSharp
Source: https://github.com/axuno/smartformat/wiki/HTML-with-CSS-or-JavaScript
This C# code demonstrates pre-processing HTML with AngleSharp to correctly format content containing placeholders, scripts, and styles using SmartFormat.
```csharp
var variables = new { Name = "John Long", City = "New York" };
// Create a new parser front-end (can be re-used)
var parser = new AngleSharp.Html.Parser.HtmlParser();
// Get the DOM representation
AngleSharp.Html.Dom.IHtmlDocument htmlDocument = parser.ParseDocument(html);
// ##### Smart.Format the HTML body: #####
htmlDocument.Body.InnerHtml = Smart.Format(htmlDocument.Body.InnerHtml, variables);
// This gets the complete HTML as a string
var result = htmlDocument.ToHtml();
```
--------------------------------
### Synchronize Two Lists with ListFormatter
Source: https://github.com/axuno/smartformat/wiki/Lists _ ListFormatter
Illustrates synchronizing and formatting elements from two different lists (char array and string array) using indexed placeholders and the ListFormatter.
```CSharp
var letters = "ABC".ToCharArray();
var words = "One|Two|Three".Split('|');
// works with indexed and named placeholders
Smart.Format("{0:list:{}\, = {1[Index]}|, }", letters, words);
// outputs: "A = One, B = Two, C = Three"
```
--------------------------------
### Enable String.Format Compatibility in SmartFormat
Source: https://github.com/axuno/smartformat/blob/main/CHANGES.md
Set SmartSettings.StringFormatCompatibility to true to enable full compatibility with string.Format. Note that this may prevent custom formatter extensions from being parsed.
```csharp
SmartSettings.StringFormatCompatibility = true;
```
--------------------------------
### Format Simple Array with ListFormatter
Source: https://github.com/axuno/smartformat/wiki/Lists _ ListFormatter
Demonstrates formatting a simple array of strings using the ListFormatter. Note the explicit cast to IList is required for indexed parameters.
```CSharp
var items = new[] { "one", "two", "three" };
// Important: You cannot use "items" as an indexed parameter directly,
// as it would be used as params with 3 args.
// So we have to cast
var result = Smart.Format("{0:list:{}\, |\, and }", (IList) items);
// Outputs: "one, two, and three"
```