projectfluent / fluent

Fluent — planning, spec and documentation
https://projectfluent.org
Apache License 2.0
1.4k stars 45 forks source link

Proper way to display ordinal numbers #359

Closed Cimbali closed 11 months ago

Cimbali commented 12 months ago

The docs give the following example:

your-rank = { NUMBER($pos, type: "ordinal") ->
   [1] You finished first!
   [one] You finished {$pos}st
   [two] You finished {$pos}nd
   [few] You finished {$pos}rd
  *[other] You finished {$pos}th
}

But it seems type: "ordinal" is not recognised. Even when ignoring the CLDR plural categories and changing the selector for exact matches we are limited:

> cat en/test.ftl
your-rank = { $pos ->
   [1] You finished first!
   [2] You finished {$pos}nd
   [3] You finished {$pos}rd
  *[other] You finished {$pos}th
}
> python3 -c 'from fluent.runtime import FluentLocalization as Loc, FluentResourceLoader as Load
print(Loc(["en"], ["test.ftl"], Load("{locale}")).format_value("your-rank", {"pos": 21}))'
You finished 21th

So what is the option to properly display irregular ordinals (X1st, X2nd, X3rd)? Is there a number format for ordinals? Is there a way to perform a calculation on the selector (here $pos > 20 + $pos % 10 could do but this will be locale-specific)? Or is my only option to enumerate them all?

eemeli commented 11 months ago

If the results are as you describe also with the example that's in the docs, then I believe you've found a bug with the Python implementation, rather than a spec bug.

Cimbali commented 11 months ago

Here’s what the python implementation does with the docs example:

> cat en/test.ftl 
your-rank = { NUMBER($pos, type: "ordinal") ->
   [1] You finished first!
   [one] You finished {$pos}st
   [two] You finished {$pos}nd
   [few] You finished {$pos}rd
  *[other] You finished {$pos}th
}
> test() {
python3 -c "from fluent.runtime import FluentLocalization as Loc, FluentResourceLoader as Load
print(Loc(['en'], ['test.ftl'], Load('{locale}')).format_value('your-rank', {'pos': $1}))"
}
> test 1
You finished 1th
> test 2
You finished 2th
> test 5
You finished 5th
> test 21
You finished 21th

I’ve just checked that the js implementation produces the expected strings first/2nd/5th/21st, so I’ll open a bug over on the python implementation.

Cimbali commented 11 months ago

Follow-up at issue projectfluent/python-fluent#192 and PR projectfluent/python-fluent#193