Localization variable formatting options
There is a mixed approach when it comes to variable formatting.
Android and iOS supports some similar formatting features based on the IEEE printf standard but they have custom features.
A common approach for web localization is that only preformatted strings are placed in the localized text and the localization library does not format the received values.
In same tools - like i18n
- you can apply a custom formatting function but there are no standard, built in formatters by default.
This is why Respresso supports a printf based formatting that unifies Android and iOS features but lets you override platform-specific variable placeholders to support any localization library.
If you don't want to use Respresso's variable formatting features, you can simply use the default %s
format that means a simple preformatted string variable.
To clarify: Respresso doesn't format your variables but lets you specify formatting instructions that are converted to platform specific variants (when possible).
Change localization variable formatting
Respresso lets you register variables for each localization (key). You can specify variable formatting for each registered variable.
Respresso provides 2 types of variable formatting:
- Printf based formatting that is required. (Defaults to
%s
that means you will provide a preformatted string value.) - Custom variable placeholders where you get full control over variable formatting.
Follow these steps to change a variable's formatting:
- Open the detailed editor panel of the localization by clicking on its key.
- Click the edit button next to the variable's name to open the variable editor dialog.
- Change the format to the desired formatting.
- Click the
OK
button to apply your change.
Respresso's printf based formatting
As mentioned above, Respresso tries to unify the variable formatting of Android and iOS. To do so, we implemented a variable formatting tool that supports almost all the features of the Android Formatter, iOS format specifiers, and the IEEE printf standard.
The syntax is the following:
%[$<argument index>][<flag>*][<width>][.<precision>][<length modifier>]<conversion>[<conversion modifier>]
Some examples:
%s
: Preformatted string from the next argument position. (conversion)%2$d
: Whole number (integer) from the 2nd argument. (argument index)%5.3f
: Real number (float/double) with minimum 3 characters long that translates to at least 2 decimal places before the decimal separator and 3 decimal places after it. (width and precision)%,d
or%'d
: A whole number with thousands separator. (Android,
and iOS'
flag is also supported that are equivalent)%Lf
: Real number (float/double). (L
length modifier means that iOS should treat the received value as along double
)%tH
: Date time formatted as 24h hours (0-23) with leading zero if necessary. (conversion modifier from Android)
Although Respresso understands these, it doesn't mean that the target format/platform supports all features.
When you specify a format that is not supported in the target format, it will translate it to the preformatted string variant. E.g. %tH
will
remain %tH
in Android strings xml while you will get %@
in iOS strings.
In the few cases when there is an alternative form for the same thing, Respresso will handle it. E.g. %'d
will remain %'d
in iOS strings while it
will be transformed to %,d
in Android strings xml.
Argument index
There is no change or extension to the IEEE printf standard.
Using the argument index, you can specify which argument/parameter should be formatted and placed to that location. This allows you to use the same
argument/parameter multiple times. E.g. a string like Time: %1$tH:%1$tM
on Android would print the something like this Time: 14:24
from a single
argument.
The argument index name may be a bit confusing as you will never use something like %0$s
. This is because it indexes the arguments of
the printf("Welcom %1$s!", "John")
function. As a result the first real variable is indexed with 1
instead of 0
.
To fix this, Respresso gives you the {{index}}
(arg. index - 1) and the {{position}}
(arg. index) placeholders when using
custom variable placeholders.
Flags
There is a single extension from Android compared to the IEEE printf standard.
You can use multiple flags within a single format but keep in mind that not all flags are supported for every conversion. Respresso will use all the specified flags converted to the target format and won't check if they are actually valid. It can cause runtime errors if you define an invalid format.
These are the flags Respresso understands:
-
: Left justified (Pad from right if width is specified)#
: Alternate form+
: Force the+
sign for positive numbers0
: Pad numbers with0
instead of space'
or,
: Use local specific thousand group separators(
: Parenthesize negative numbers
Width
There is no change or extension to the IEEE printf standard.
This is positive (non-zero) number that specifies the minimum length of the formatted string. It is padded when the result is shorter. If not specified otherwise, it is left padded with spaces.
Please note that 0
is not valid width parameter as it will mean the 0
flag.
Precision
There is no change or extension to the IEEE printf standard.
A .
followed with a non-negative whole number that specifies the decimal places after the decimal separator.
Length modifier
There is a single exclusion due to Android compared to the IEEE printf standard.
This modifier specifies how the received parameter should be treated on native languages, like Objective-C. This parameter is not present in Android strings xml.
These are the length modifiers Respresso understands:
hh
: Charh
: Short intl
: Long intll
: Long long intj
: Int maxz
: Size (size_t)L
: Long double
Length modifiers can use signed or unsigned representation depending on the conversion that is applied to. To learn more, you can visit the C++ reference page of printf.
Please note that the IEEE printf standard t
length modifier is excluded as it is colliding with the Android's Date/Time conversion which is much more useful.
Conversion
There are a few extensions compared to the IEEE standard.
The applied conversion defines the formatting function, this is why this is the only required part of the format.
These are the standard conversions Respresso understands:
s
,S
or@
: String value (preformatted string or an object converted to string)d
ori
: Whole number in decimal representation.f
orF
: Real number in decimal representation.c
orC
: Single character.o
: Whole number in octal representation.x
orX
: Whole number in hexadecimal representation.e
orE
: Real number in decimal representation in scientific notation.g
orG
: Real number in compact decimal representation.a
orA
: Real number in hexadecimal representation.p
: Pointer address. (Android doesn't support it)%
: Percent literal. (Not argument consuming variable. Used to escape the%
character -%%
will translate to%
.)
Do NOT use the percent literal (%%
) in variable formatting, it is only supported to properly import localizations.)
These are the non-standard conversions Respresso understands:
b
orB
: Boolean value. (Android only)h
orH
: String in hexadecimal representation. (Android only)t
orT
: Date/Time conversion that is followed by a conversion modifier. (Android only)
Conversion modifier (Android only)
This is not part of the IEEE printf standard.
It is an extension from Android's Date/Time conversion.
Usable only with conjunction with the t
or T
conversion.
These are the conversion modifiers Respresso understands:
H
: Hour of day (24h - 2 digits)I
: Hour of day (12h - 2 digits)k
: Hour of day (24h)l
: Hour of day (12h)M
: MinuteS
: SecondM
: Millisecond (3 digits)N
: Nanosecond (9 digits)p
: AM/PM indicatorz
: Numeric time-zone offsetZ
: Time-zones
: Epoch secondsQ
: Epoch millisecondsB
: Full month nameb
: Short month nameh
: Short month name aliasA
: Full day of weeka
: Short day of weekC
: Century (2 digits)Y
: Year (4 digits)y
: Year (2 digits)j
: Day of year (3 digits)m
: Month of year (2 digits)d
: Day of month (2 digits)e
: Day of monthR
: Time in hours and minutes (24h)T
: Time in hours minutes and seconds (24h)r
: Time in hours minutes and seconds (12h)D
: Formatted date (Equivalent with%tm/%td/%ty
)F
: ISO Datec
: Compact formatted date time (Equivalent with%ta %tb %td %tT %tZ %tY
)