Formatting - LunarWatcher/JVMI18N GitHub Wiki

What is a String resource without formatting?

Generally, the default String.format method has a lot of power behind it, but it requires a lot of tweaking and if-else statements for even tiny changes where a given variable matters. For an instance if you have a number, you'd need if-else statements to show the appropriate form. So if you want to show item when x = 1 and items if it is <= 0 or > 1, you'd normally need to do a lot of work to get that to work.

This framework does a lot of that lifting for you, by adding support for formatting like this just in the text. First off though, basic formatting:

resourceKey=This is a sample text to be formatted and make it $[int] times more awesome

At this point, you should have the bundle or bundles loaded into the Translation instance. This is documented on the setup page in this wiki.

The library itself offers a formatter: DefaultFormatter, which extends Formatter. This means you can implement your own formatter if you want to, but it isn't required. The default formatter comes with a lot of features like the advanced formatting you're going to see later.

When you have loaded the resource using the .get method in Translation, you create the formatter:

DefaultFormatter formatter = new DefaultFormatter(translation);

and format the loaded resource:

String formatted = formatter.formatInput(loadedResource, new Object[]{1000000});

The output?

This is a sample text to be formatted and make it 1000000 times more awesome

But the fun doesn't just end there. The library has a powerful backend for formatting that can go further than just loading basic strings. For an instance, you can do this:

sample=This is $[string], a $[string] that makes internationalization $[int,<=0 "times",=1 "time",>1 "times"] easier!

and formatting:

String zero = formatter.formatInput(loadedResource, new Object[]{"JVMI18N", "library written in Kotlin and Java for the JVM", 0});
String one = formatter.formatInput(loadedResource, new Object[]{"JVMI18N", "library written in Kotlin and Java for the JVM", 1});
String tenK = formatter.formatInput(loadedResource, new Object[]{"JVMI18N", "library written in Kotlin and Java for the JVM", 10000});

And if you print those, you'll see that the actual output shows time or times depending on the number passed. This makes translating, or just keeping strings with plural or not, much easier. No need for multiple resources for that part.

The types of formattable data that supports this are the numbers only (number, int, float and double). They work with decimal points as well, meaning you can take it a step further:

sample2=Often, translating just $[int,=0 "no strings",=1 "one string",>=2 "a few strings",<0 "a negative amount of Strings"] isn't enough. Often, you want to take it in $[int,=1 "one step", >=2 "multiple steps",=100 "a specific amount of steps"] to get there

This can, as already seen be formatted and data loaded in:

String formattedSample2 = formatter.formatInput(sample2, new Object[]{10, 100});
String _formattedSample2 = formatter.formatInput(sample2, new Object[]{10, 99});

= is prioritized over the others as it is the most important one. If the value is exactly x, that form is the one to prefer. If the value doesn't match a given statement, and nothing matches on the = checks, it checks for >= and <=. After this it goes for the last value available in the options.

It's worth noting that if the input doesn't match anything in the supplied format, the number alone will be formatted into the text.

And this works with decimal values as well:

sample3=$[double,=0.1 "Tiny",>0 "Existant",<0 "Not existant"]

And the type number is essentially a wildcard for numbers. Place whatever number in here, which is particularly useful when formatting a number that can be either an integer, float or double.

And finally, there's the -e flag. The flag is used whenever you want to remove the input and only keep the text. For an instance:

sample4=$[int,=1 -e "one item",>= 2 "items"]

When formatted, if the input is one the String will simply say one item.

The formatter itself has a bunch of different supported actions, and more will be added in the future.

Supported types

$[TYPE HERE] - $[int]

  • int
  • float
  • double
  • number
  • string

Supported operators

$[TYPE,OPERATOR2 "some text"] - $[integer,>2 "some text"]

  • <
  • =

  • <=
  • =

Supported flags:

  • None defined or -d : default flag
  • -e : excluding. Removes the input and uses the custom String only
⚠️ **GitHub.com Fallback** ⚠️