Releases: axuno/SmartFormat
v3.0.0-alpha.4
Changes on top of v3.0.0-alpha.3:
1. Further improvement in performance
2. Added LocalizationFormatter (#176)
Features
- Added
LocalizationFormatterto localize literals and placeholders - Added
ILocalizationProviderand a standard implemention asLocalizationProvider, which handlesresxresource files. A fallback culture can be set. It will be used, in case no item for a certain culture could be found in any of the resources.LocalizationProvidercan search an unlimited number of defined resoures. SmartSettingswere exended with categoryLocalization. That way, customIFormatters can also make use of localization, if needed.- Added
LocalizationFormattingException, which is derived fromFormattingExceptionto easily identify this kind of issues
Examples
Culture-specific results shown here are included in embedded resource files, which are omitted for brevity.
a) Localize pure literals into Spanish:
// culture supplied as a format option
_ = Smart.Format(culture, "{:L(en):WeTranslateText}");
// culture supplied as an argument to the formatter
var culture = CultureInfo.GetCultureInfo("es");
_ = Smart.Format(culture, "{:L:WeTranslateText}");
// result for both: "Traducimos el texto"b) Localized strings may contain placeholders
_ = Smart.Format("{0} {1:L(es):has {:#,#} inhabitants}", "X-City", 8900000);
// result: "X-City tiene 8.900.000 habitantes"
_ = Smart.Format("{0} {1:L(es):has {:#,#} inhabitants}", "X-City", 8900000);
// result: "X-City has 8,900,000 inhabitants"c) Localization can be used together with other formatters
_ = Smart.Format("{0:plural:{:L(en):{} item}|{:L(en):{} items}}", 0;
// result for English: 0 items
_ = Smart.Format("{0:plural:{:L(fr):{} item}|{:L(fr):{} items}}", 0;
// result for French: 0 élément
_ = Smart.Format("{0:plural:{:L(fr):{} item}|{:L(fr):{} items}}", 200;
// result for French: 200 éléments3. Refactored PluralLocalizationFormatter (#209)
- Constructor with string argument for default language is obsolete.
- Property
DefaultTwoLetterISOLanguageNameis obsolete. - Culture is now determined in this sequence (same as with
LocalizationFormatter):
a) Get the culture from theFormattingInfo.FormatterOptions.
b) Get the culture from theIFormatProviderargument (which may be aCultureInfo) toSmartFormatter.Format(IFormatProvider, string, object?[])
c) TheCultureInfo.CurrentUICulture
4. Refactored TimeFormatter (#220, #221)
- Constructor with string argument for default language is obsolete.
- Property
DefaultTwoLetterISOLanguageNameis obsolete. - Culture is now determined in this sequence (same as with
LocalizationFormatterandPluralLocalizationFormatter):
a) Get the culture from theFormattingInfo.FormatterOptions.
b) Get the culture from theIFormatProviderargument (which may be aCultureInfo) toSmartFormatter.Format(IFormatProvider, string, object?[])
c) TheCultureInfo.CurrentUICulture - New: With the extended
CommonLanguagesTimeTextInfo,TimeFormatterincludes French, Spanish, Portuguese, Italian and German as new languages besides English out-of-the-box. - New: With e.g.
TimeFormatter.FallbackLanguage = "en";, this fallback language will be used, if no supported language could be found. - New: Custom languages can now easily be added to
CommonLanguagesTimeTextInfo. Custom languages override built-in definitions.var language = "nl"; // dummy - it's English, not Dutch ;-) TimeTextInfo custom = new( pluralRule: PluralRules.GetPluralRule(language), week: new[] { "{0} week", "{0} weeks" }, day: new[] { "{0} day", "{0} days" }, hour: new[] { "{0} hour", "{0} hours" }, minute: new[] { "{0} minute", "{0} minutes" }, second: new[] { "{0} second", "{0} seconds" }, millisecond: new[] { "{0} millisecond", "{0} milliseconds" }, w: new[] { "{0}w" }, d: new[] { "{0}d" }, h: new[] { "{0}h" }, m: new[] { "{0}m" }, s: new[] { "{0}s" }, ms: new[] { "{0}ms" }, lessThan: "less than {0}"); CommonLanguagesTimeTextInfo.AddLanguage(language, custom)
- Changed:
a) This notation - using formats as formatter options - was allowed in Smart.Format v2.x, but is now depreciated. It is still detected and working, as long as the format part is left emptyb) This format string is recommended for Smart.Format v3 and later. It allows for including the language as an option to thevar formatDepreciated = "{0:time(abbr hours noless)}";
TimeFormatter:// Without language option: var formatRecommended = "{0:time:abbr hours noless:}"; // With language option: var formatRecommended = "{0:time(en):abbr hours noless:}";
- PRs for extending built-in languages are welcome.
- Example:
var timeSpan = new TimeSpan(1,1,1,1,1) Smart.Format("{0:time(en):hours minutes}", timeSpan); // result: "25 hours 1 minute" Smart.Format("{0:time(fr):hours minutes}", timeSpan); // result: "25 heures 1 minute"
v2.7.1
v3.0.0-alpha.3
Changes on top of v3.0.0-alpha.2:
1. NullFormatter processes complex formats:
- Behavior is comparable to
ChooseFormatter - Allows for nested formats
- More plausibility checks
2. NewtonsoftJsonSource: fix evaluating null values
3. Add missing formatters to Smart.CreatDefaultFormatter
- include IsMatchFormatter
- include NullFormatter
4. Improved parsing of HTML input
Introduced experimental bool ParserSettings.ParseInputAsHtml.
The default is false.
If true, theParser will parse all content inside <script> and <style> tags as LiteralText. All other places may still contain Placeholders.
This is because <script> and <style> tags may contain curly or square braces, that interfere with the SmartFormat {Placeholder}.
Best results can only be expected with clean HTML: balanced opening and closing tags, single and double quotes. Also, do not use angle brackets, single and double quotes in script or style comments.
SmartFormat is not a fully-fledged HTML parser. If this is required, use AngleSharp or HtmlAgilityPack.
v3.0.0-alpha.2
Changes since v3.0.0-alpha.1:
1. All Format() methods accept nullable args
- Opposed to
string.Formatnull(able) arguments are allowed. - Changes effect classes
SmartandSmartFormatter
2. ListFormatter will be initialized only once
v3.0.0-alpha.1
Significant improvements of performance:
BenchmarkDotNet performance tests for formatters and ISources now show (depending on different input format strings) the following improvements compared to v2.7.0:
- increase in speed by up to 40%
- decrease of GC pressure (collects are only GC Generation 0, allocated memory reduced by up to 60%)
Formatting measured with a cached parsed Format, and including the result string returned to the caller. Parser was already optimized with PR #187.
v2.7.0.0
- Fixed broken backward compatibilty introduced in v2.6.2 (issues referenced in #148, #147, #143).
- Fixed: Take an erroneous format string like
"this is {uncomplete"(missing closing brace). Before v2.7.0 the parser handled{uncompleteas aTextLiteral, not as an erroneousPlaceholder. - Fixed: Since v1.6.1 there was an undiscovered issue: If the
Parserencountered aParsingError.TooManyClosingBraces, this closing brace was simply "swallowed-up". This way, the result withParser.ErrorAction.MaintainTokensdiffers from the original format string. From v2.7.0, the redundant closing brace is handled as aTextLiteral. - If you have issues formatting HTML with CSS and/or JavaScript included, please read the bullet-proof How-to in the Wiki
v2.6.2.0
v2.6.1.0
v2.5.3.0
v2.5.3.0-preview1
ListFormatter will only process IList sources.