deltachat / deltachat-desktop

Email-based instant messaging for Desktop.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

i18n: wrong order of substitutions for some strings

WofWca opened this issue · comments

  • Operating System (Linux/Mac/Windows/iOS/Android):
  • Delta Chat Version: 1.45
  • Expected behavior: a string %2$s가 %1$s를 멤버로 추가함 is substituted as THE ADDED 가 THE ADDER를 멤버로 추가함
  • Actual behavior: it is substituted as THE ADDER 가 THE ADDED를 멤버로 추가함, which is the wrong way around.
  • Steps to reproduce the problem:
    1. Switch to Korean language (ko).
    2. Be in the group where someone adds someone else.
    3. See the message that is printed when that happens.
  • Screenshots:
  • Logs:

How to find (some) strings that are wrong: search for %2.*%1. There are 94 occurrences for 16 languages currently.

The responsible code:

let c = 0
return message.replace(/(?:%\d\$[\w\d])|(?:%[\w\d])/g, () => {
if (
substitutions === undefined ||
typeof substitutions[c] === 'undefined'
) {
log.error(`Missing ${c} argument for key %c'${key}'`)
return ''
}
return substitutions[c++].toString()
})

It assumes that the substitutions are always in the same order for all strings for all languages.
And if you feel like "it's just a matter of looking at the digits after %, keep in mind that some strings only have one substitution, and some strings have several substitutions, but they are not numbered (such as ask_send_following_n_files_to

It feels like it's about time to use a library for this. Or write one, and cover it with tests. Or convert the original xml files to a better-supported format with a tried-and-tested converter. We already have code that converts XML to JSON.

Also as a part of this I guess this

fileCount > 1 ? [String(fileCount), chatName] : [chatName],

needs to be fixed to support non-English plural rules.

good catch! thanks a lot!

it's all a bit tricky, indeed.

isn't there a printf()-or-so with indexed parameters on javascript? then one would just need to convert the argument syntax.

otherwise, if it helps, indexed-parameters and not-indexed-parameters are not mixed in the same string. and, there is currently max. 3 indexed parameters, so, instead of a loop, we could do sth. like the following pseudocode:

substitude_translations(str, param, plurals_amount = 0) {
  str.replace('%1$s', param[0])
  str.replace('%2$s', param[1])
  str.replace('%3$s', param[2])

  str.replace_once('%s', param[0])
  str.replace_once('%s', param[1])
  str.replace_once('%s', param[2])
  
  str.replace('%d', plurals_amount)
}

isn't there a printf()-or-so with indexed parameters on javascript?

There is not built-in thing that solves this problem.