A lightweight text templating library written in C# which can be a drop-in replacement for string.Format
SmartFormat has transitioned to using .NET Framework 4.6.2 (net462)
as its target framework, replacing the now unsupported .NET Framework 4.6.1 (net461)
. The support for net461
ended in 2022, while net462
will continue to receive support until January 2027.
Switching to a different patch version of a target framework is generally not considered a breaking change. This is referred to as an in-place update by Microsoft. In the case of SmartFormat, we have not encountered any runtime issues with the existing API after this transition.
The same holds true for the new netstandard2.0
reference to ZString.
SmartFormat has expanded its compatibility by adding .NET 6.0 (net60)
and .NET 8.0 (net80)
as additional target frameworks. You can find details about their end of support here.
We have removed the SmartFormat.ZString
assembly and replaced it with a reference to the ZString package. This change does not affect the API.
Thanks to @thompson-tomo for his first contribution with https://github.com/axuno/SmartFormat/pull/377
Full Changelog: https://github.com/axuno/SmartFormat/compare/v3.3.2...v3.4.0
Full Changelog: https://github.com/axuno/SmartFormat/compare/v3.3.1...v3.3.2
PluralRule for DualFromZeroToTwo: Now a value of 2 is covered and will not throw. Frend is one of the affected languages. Closes #369 in https://github.com/axuno/SmartFormat/pull/370
Dictionary<string, PluralRuleDelegate> PluralRule.IsoLangToDelegate
holds delegate
s with the pluralization rule per language. Changing a value of this dictionary will change the pluralization rules globally. This is not recommended, but possible. After a change calling PluralRules.RestoreDefault()
will restore the default rules.
Full Changelog: https://github.com/axuno/SmartFormat/compare/v3.3.0...v3.3.1
LocalizationFormatter
by @zacateras in https://github.com/axuno/SmartFormat/pull/350. This is useful, if the string to localize contains a SmartFormat placeholder instead of a pure text. Example: If the format is "{:L:{ProductType}}"
, the ProductType
placeholder will be replaced with the variable content "pen". "pen" will in turn be localiced to "bic" for the FR
locale.DictionarySource
has an option to evaluate IReadOnlyDictionary<TKey,TValue>
sources by @axunonb in https://github.com/axuno/SmartFormat/pull/353. To enable, set DictionarySource.IsIReadOnlyDictionarySupported
to true
(default is false
). This is for types that only implement IReadOnlyDictionary<TKey,TValue>
, but not IDictionary
.Full Changelog: https://github.com/axuno/SmartFormat/compare/v3.2.2...v3.3.0
PluralLocalizationFormatter
does not treat a numeric string as valid argument (resolves #345, restore behavior of v3.1.0 and before) in https://github.com/axuno/SmartFormat/pull/346
Bump version to v3.2.2
Meaning: Smart.Format("{0:{}|is null or empty}", "1234");
will not implicitly invoke PluralLocalizationFormatter
but instead ConditionalFormatter
. So the result is "1234" as to be expected. A string argument to PluralLocalizationFormatter
is never accepted, even if it could be converted to a number.
Full Changelog: https://github.com/axuno/SmartFormat/compare/v3.2.1...v3.2.2
Fix: Auto-detection of PluralLocalizationFormatter does not throw for values not convertible to decimal by @axunonb in https://github.com/axuno/SmartFormat/pull/330 Resolves #329 (Thanks to @BtbN)
Current behavior, introduced in v3.2.0:
When PluralLocalizationFormatter.CanAutoDetect == true
, values that are not convertible to decimal
will throw then trying to IConvertible.ToDecimal(...)
New behavior, equivalent to v3.1.0:
When PluralLocalizationFormatter.CanAutoDetect == true
, for values that are not convertible to decimal
, IFormatter.TryEvaluateFormat(...)
will return false
Fix processing for Singular languages by @axunonb in https://github.com/axuno/SmartFormat/pull/322
Full Changelog: https://github.com/axuno/SmartFormat/compare/v3.2.0...v3.2.1
IConvertable
support for PluralLocalizationFormatter
and ConditionalFormatter
ListFormatter
IEnumerable
s and IList
s: In v1.6.1
a Selector was tested for having the name "index", even if data was not an IList
, and returned the CollectionIndex
. This is now implemented again in the ListFormatter.TryEvaluateSelector(...)
ParentPlaceholder
property for item Format
sPooledObject<T>
where possible, so objects will be returned to ObjectPool
also in case of exceptionsFormatItem.AsSpan()
returns the correct nameCysharp.Text
are now internalis
instead of checking the type info. by @karljj1 in https://github.com/axuno/SmartFormat/pull/293
Full Changelog: https://github.com/axuno/SmartFormat/compare/v3.1.0...v3.2.0
Newtonsoft.Json prior to version 13.0.1 is vulnerable to Insecure Defaults due to improper handling of expressions with high nesting level that lead to StackOverFlow exception or high CPU and RAM usage. Exploiting this vulnerability results in Denial Of Service (DoS).
Package reference updated to a minimum version 13.0.1
This is a feature update, that is released upon feedback from the community.
Thread-safe mode is now enabled by default:
SmartSettings.IsThreadSafeMode == true
.
This has no impact on the API.
In case SmartFormat is exclusively utilized in a single-threaded context, SmartSettings.IsThreadSafeMode=false
should be considered for enhanced performance.
Smart
Methods for FormattingStatic Smart
methods like Smart.Format(format, args) can now be called in an async
/ multi-threaded context.
The SmartFormatter
instance returned by Smart.Default
is flagged with the ThreadStatic
attribute.
See more details in the Wiki: Async and Thread Safety
ListFormatter
may have Placeholders in "spacers"Thanks to karljj1 for the PR.
Before v3.1.0 the format options for ListFormatter
could only contain literal text. Now Placeholder
s are allowed.
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"
SubStringFormatter
The formatter now accecpts a format argument with a nested Placeholder
that lets you format the result of the sub-string operation.
Example: Convert the sub-string to lower-case:
Smart.Format("{0:substr(0,2):{ToLower}}", "ABC");
Reasoning: Enhancement
KeyValuePairSource
, PersistentVariablesSource
and GlobalVariablesSource
can now process "null if nullable"
Reasoning: Enhancement
TemplateFormatter
The name of the formatter is now "t"
(was "template" before).
Reasoning: Minimize the format string
ChooseFormatter
, ConditionalFormatter
, IsMatchFormatter
, ListFormatter
, PluralLocalizationFormatter
, SubStringFormatter
Reasoning: Avoid conflicts with reserved characters
Reasoning: Enhancement
An implementation of a magic leading colon in order to identify whether ConditionalFormatter
or PluralLocalizationFormatter
should be invoked, was removed.
Reasoning:
This is undocumented and unnecessary.
Adding the formatter name in the format string achieves the same target.