unsplash / intlc

Compile ICU messages into code. Supports TypeScript and JSX. No runtime.
MIT License
56 stars 3 forks source link

Add plural expansion #145

Closed samhh closed 2 years ago

samhh commented 2 years ago

Closes #138.

Adds plural expansion to the internal CLI, operating via stdin and stdout to make its use prior to zipping comfortable. Because we only expand plurals with a wildcard, this should never result in a different compiled type signature (other/wildcard means widened number as opposed to literals), and as such we shouldn't need to apply this to our own master English translations. This means we do not add plural forms for a literal plural like {n, plural, =0 {x} =1 {y}} (which compiles to n: 0 | 1), but I don't think we use these much. Plural expansion applies to both plural and selectordinal, which each fall under the Plural type in our AST.

$ echo '{"f":{"message": "You have {n, plural, one {cat} other {cats}}!"}}' | intlc-internal expand-plurals
{"f":{"message":"You have {n, plural, one {cat} zero {cats} two {cats} few {cats} many {cats} other {cats}}!","backend":"ts","description":null}}

Traversing streams ergonomically continues to be a challenge (#48). The CLI interfaces could probably do with some tidying up but that can wait for another PR.

samhh commented 2 years ago

Once this is merged/released, we can enable it alongside flattening in unsplash-web?

Yep. Following a release we can bump the Nix derivation and use it something like this:

diff --git a/localization/zip.sh b/localization/zip.sh
index 0ed80a4015..bfb5fc9ce1 100755
--- a/localization/zip.sh
+++ b/localization/zip.sh
@@ -7,7 +7,7 @@ zip_file() {
   if [[ $file == *.json ]]
   then
     tmp=$(mktemp)
-    intlc flatten "$file" | prettier --parser=json > "$tmp"
+    intlc flatten "$file" | intlc-internal expand-plurals | prettier --parser=json > "$tmp"
     mv "$tmp" "$file"
   fi
   zip translations.zip "$file"

I think the order of flattening and plural expansion shouldn't matter however for some reason we're not using stdin for flattening.