Skip to content

Releases: axuno/SmartFormat

v3.0.0-alpha.4

25 Oct 20:27
3f76131

Choose a tag to compare

v3.0.0-alpha.4 Pre-release
Pre-release

Changes on top of v3.0.0-alpha.3:

1. Further improvement in performance

2. Added LocalizationFormatter (#176)

Features

  • Added LocalizationFormatter to localize literals and placeholders
  • Added ILocalizationProvider and a standard implemention as LocalizationProvider, which handles resx resource 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. LocalizationProvider can search an unlimited number of defined resoures.
  • SmartSettings were exended with category Localization. That way, custom IFormatters can also make use of localization, if needed.
  • Added LocalizationFormattingException, which is derived from FormattingException to 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éments

3. Refactored PluralLocalizationFormatter (#209)

  • Constructor with string argument for default language is obsolete.
  • Property DefaultTwoLetterISOLanguageName is obsolete.
  • Culture is now determined in this sequence (same as with LocalizationFormatter):

    a) Get the culture from the FormattingInfo.FormatterOptions.

    b) Get the culture from the IFormatProvider argument (which may be a CultureInfo) to SmartFormatter.Format(IFormatProvider, string, object?[])

    c) The CultureInfo.CurrentUICulture

4. Refactored TimeFormatter (#220, #221)

  • Constructor with string argument for default language is obsolete.
  • Property DefaultTwoLetterISOLanguageName is obsolete.
  • Culture is now determined in this sequence (same as with LocalizationFormatter and PluralLocalizationFormatter):

    a) Get the culture from the FormattingInfo.FormatterOptions.

    b) Get the culture from the IFormatProvider argument (which may be a CultureInfo) to SmartFormatter.Format(IFormatProvider, string, object?[])

    c) The CultureInfo.CurrentUICulture
  • New: With the extended CommonLanguagesTimeTextInfo, TimeFormatter includes 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 empty
    var formatDepreciated = "{0:time(abbr hours noless)}";
    b) This format string is recommended for Smart.Format v3 and later. It allows for including the language as an option to the 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

21 Oct 08:16
ca28b30

Choose a tag to compare

Changes

  • Fixed: #179 DualFromZeroToTwo plural rule. Thanks to @OhSoGood
  • Fixed: #211 Illegal placeholder characters that are not 8-bit, will no more throw unexpected ThrowByteOverflowException. Thanks to @bogatykh

v3.0.0-alpha.3

20 Sep 21:25
b7f9100

Choose a tag to compare

v3.0.0-alpha.3 Pre-release
Pre-release

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

21 Sep 19:26
3188ed9

Choose a tag to compare

v3.0.0-alpha.2 Pre-release
Pre-release

Changes since v3.0.0-alpha.1:

1. All Format() methods accept nullable args

  • Opposed to string.Format null(able) arguments are allowed.
  • Changes effect classes Smart and SmartFormatter

2. ListFormatter will be initialized only once

v3.0.0-alpha.1

29 Aug 23:40
71fdfd6

Choose a tag to compare

v3.0.0-alpha.1 Pre-release
Pre-release

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

10 Apr 22:09

Choose a tag to compare

  • 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 {uncomplete as a TextLiteral, not as an erroneous Placeholder.
  • Fixed: Since v1.6.1 there was an undiscovered issue: If the Parser encountered a ParsingError.TooManyClosingBraces, this closing brace was simply "swallowed-up". This way, the result with Parser.ErrorAction.MaintainTokens differs from the original format string. From v2.7.0, the redundant closing brace is handled as a TextLiteral.
  • 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

17 Feb 21:15
0f0f545

Choose a tag to compare

  • Fix: Fully implemented all Settings.ParseErrorAction, see #143 - Thanks to Anders Jonsson

v2.6.1.0

12 Feb 17:13
742d4d5

Choose a tag to compare

  • Fixed #136
  • Upgraded test project to netcoreapp3.1
  • Enhanced SubString extension as described in PR142 - Thanks to Anders Jonsson
  • Migrated project with Nullable Reference Types (NRT) enabled

v2.5.3.0

10 Nov 20:57

Choose a tag to compare

Bugfix release

v2.5.3.0-preview1

02 Nov 21:07

Choose a tag to compare

v2.5.3.0-preview1 Pre-release
Pre-release

ListFormatter will only process IList sources.