All Projects ā†’ jeffijoe ā†’ Messageformat.net

jeffijoe / Messageformat.net

Licence: mit
ICU MessageFormat implementation for .NET.

Labels

Projects that are alternatives of or similar to Messageformat.net

Texttable
Swift package for easily rendering text tables. Inspired by the Python tabulate library.
Stars: āœ­ 82 (-36.43%)
Mutual labels:  formatter
Snowonder
šŸ”® Magical import declarations formatter for Xcode
Stars: āœ­ 100 (-22.48%)
Mutual labels:  formatter
Javascriptprettier
A Visual Studio extension
Stars: āœ­ 118 (-8.53%)
Mutual labels:  formatter
Black Playground
ambv/black online demo
Stars: āœ­ 83 (-35.66%)
Mutual labels:  formatter
Laravel Oh Generators
This package extends the core file generators that are included with Laravel 5 or later.
Stars: āœ­ 96 (-25.58%)
Mutual labels:  formatter
Swimat
An Xcode formatter plug-in to format your swift code.
Stars: āœ­ 1,388 (+975.97%)
Mutual labels:  formatter
Aspnetcorecsvimportexport
ASP.NET Core CSV import export custom formatters
Stars: āœ­ 77 (-40.31%)
Mutual labels:  formatter
Editorconfig Netbeans
A NetBeans IDE plugin supporting the EditorConfig standard. ā›ŗ
Stars: āœ­ 123 (-4.65%)
Mutual labels:  formatter
Kibana Object Format
A Kibana plugin for displaying objects and arrays of objects.
Stars: āœ­ 100 (-22.48%)
Mutual labels:  formatter
Atom Beautify
šŸ“£ Help Wanted - Looking for Maintainer: https://github.com/Glavin001/atom-beautify/issues/2572 | šŸ’„ Universal beautification package for Atom editor (āš ļø Currently migrating to https://github.com/Unibeautify/ and have very limited bandwidth for Atom-Beautify Issues. Thank you for your patience and understanding ā¤ļø )
Stars: āœ­ 1,501 (+1063.57%)
Mutual labels:  formatter
Parallel Prettier
Concurrent prettier runner
Stars: āœ­ 84 (-34.88%)
Mutual labels:  formatter
Unimport
A linter, formatter for finding and removing unused import statements.
Stars: āœ­ 96 (-25.58%)
Mutual labels:  formatter
Prettier
Prettier is an opinionated code formatter.
Stars: āœ­ 41,411 (+32001.55%)
Mutual labels:  formatter
Plugin Php
Prettier PHP Plugin
Stars: āœ­ 1,243 (+863.57%)
Mutual labels:  formatter
Javascript Number Formatter
Lightweight & Fast JavaScript Number Formatter
Stars: āœ­ 119 (-7.75%)
Mutual labels:  formatter
Elm Format
elm-format formats Elm source code according to a standard set of rules based on the official Elm Style Guide
Stars: āœ­ 1,240 (+861.24%)
Mutual labels:  formatter
Codeview
Codeview is an Android library that lets you preview code in webview very easy and simple with highlights and colors.
Stars: āœ­ 103 (-20.16%)
Mutual labels:  formatter
Vue Filters Kit
A collection of useful custom filters for Vue.js(v2.x.x) apps.
Stars: āœ­ 125 (-3.1%)
Mutual labels:  formatter
Auto Correct
Automatically add whitespace between CJK (Chinese, Japanese, Korean) and half-width characters (alphabetical letters, numerical digits and symbols).
Stars: āœ­ 122 (-5.43%)
Mutual labels:  formatter
Pretty Yaml
PyYAML-based module to produce pretty and readable YAML-serialized data
Stars: āœ­ 110 (-14.73%)
Mutual labels:  formatter

MessageFormatter for .NET

- better UI strings.

Build

This is an implementation of the ICU Message Format in .NET. For official information about the format, go to: http://userguide.icu-project.org/formatparse/messages

Quickstart

var mf = new MessageFormatter();

var str = @"You have {notifications, plural,
              zero {no notifications}
               one {one notification}
               =42 {a universal amount of notifications}
             other {# notifications}
            }. Have a nice day, {name}!";
var formatted = mf.FormatMessage(str, new Dictionary<string, object>{
  {"notifications", 4},
  {"name", "Jeff"}
});

//Result: You have 4 notifications. Have a nice day, Jeff!

Or, if you don't like dictionaries, and don't mind a bit of reflection..

var formatted = mf.FormatMessage(str, new {
  notifications = 0,
  name = "Jeff"
});

//Result: You have no notifications. Have a nice day, Jeff!

You can use a static method, too:

var formatted = MessageFormatter.Format(str, new {
  notifications = 1,
  name = "Jeff"
});

//Result: You have one notification. Have a nice day, Jeff!

Installation

Either clone this repo and build it, or install it with NuGet:

Install-Package MessageFormat

Features

  • It's fast. Everything is hand-written; no parser-generators, not even regular expressions.
  • It's portable. The library is targeting .NET Standard 1.1.
  • It's compatible with other implementations. I've been peeking a bit at the MessageFormat.js library to make sure the results would be the same.
  • It's (relatively) small. For a .NET library, ~25kb is not a lot.
  • It's very white-space tolerant. You can structure your blocks so they are more readable - look at the example above.
  • Nesting is supported. You can nest your blocks as you please, there's no special structure required to do this, just ensure your braces match.
  • Adding your own formatters. I don't know why you would need to, but if you want, you can add your own formatters, and take advantage of the code in my base classes to help you parse patterns. Look at the source, this is how I implemented the built-in formatters.
  • Exceptions make at least a little sense. When exceptions are thrown due to a bad pattern, the exception should include useful information.
  • There are unit tests. Run them yourself if you want, they're using XUnit.
  • Built-in cache. If you are formatting messages in a tight loop, with different data for each iteration, and if you are reusing the same instance of MessageFormatter, the formatter will cache the tokens of each pattern (nested, too), so it won't have to spend CPU time to parse out literals every time. I benchmarked it, and on my monster machine, it didn't make much of a difference (10000 iterations).

Performance

If you look at MessageFormatterCachingTests, you will find a "with cache" and "without cache" test.

My machine runs on a Core i7 3960x, and with about 100,000 iterations with random data (generated beforehand), it takes about 2 seconds (1892ms) with the cache, and about 3 seconds (3236ms) without it. These results are with a debug build, when it is in release mode the time taken is reduced by about 40%! :)

Supported formats

Basically, it should be able to do anything that MessageFormat.js can do.

  • Select Format: {gender, select, male{He likes} female{She likes} other{They like}} cheeseburgers
  • Plural Format: There {msgCount, plural, zero {are no unread messages} one {is 1 unread message} other{are # unread messages}}. (where # is the actual number, with the offset (if any) subtracted).
  • Simple variable replacement: Your name is {name}

Adding your own pluralizer functions

Same thing as with MessageFormat.js, you can add your own pluralizer function. The Pluralizers property is a IDictionary<string, Pluralizer>, so you can remove the built-in ones if you want.

var mf = new MessageFormatter();
mf.Pluralizers.Add("<locale>", n => {
  // Ā“nĀ“ is the number being pluralized.
  if(n == 0)
    return "zero";
  if(n == 1)
    return "one";
  return "other";
});

There's no restrictions on what strings you may return, nor what strings you may use in your pluralization block.

var mf = new MessageFormatter(true, "en"); // true = use cache
mf.Pluralizers["en"] = n =>
{
    // Ā“nĀ“ is the number being pluralized.
    if (n == 0)
        return "zero";
    if (n == 1)
        return "one";
    if (n > 1000)
        return "thatsalot";
    return "other";
};

mf.FormatMessage("You have {number, plural, thatsalot {a shitload of notifications} other {# notifications}}", new Dictionary<string, object>{
  {"number", 1001}
});

Escaping literals

Simple - the literals are {, } and # (in a plural block). If literals occur in the text portions, then they need to be quoted by enclosing them in pairs of single quotes ('). A pair of single quotes always represents one single quote ('' -> '), which still applies inside quoted text. (This '{isn''t}' obvious ā†’ This {isn't} obvious)

Anything else?

There's not a lot - Alex Sexton of MessageFormat.js did a great job documenting his library, and like I said, I wrote my implementation so it would be (somewhat) compatible with his.

Bugs / issues

If you have issues with the library, and the exception makes no sense, please open an issue and include your message, as well as the data you used.

Todo

  • Built-in locales (currently only en is added per default).

Don't expect this in the near future - you're welcome to submit a PR. :)

Author

I'm Jeff Hansen, a software developer who likes to fiddle with string parsing when it is not too difficult. I also do a lot of ASP.NET Web API back-end development, and quite a bit of web front-end stuff.

You can find me on Twitter: @jeffijoe.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].