ActivityPubのローカリゼーション文字列における複数形のハンドリング

ActivityPub プラグインで、私の意見では複数形にする必要がある文字列がいくつか見つかりました。

新しいトピックの最初の投稿は、投稿から %{delay_minutes} 分後に公開されます。

discourse-activity-pub/config/locales/client.en.yml at a49ec5c4f5acac28bafbc1c57c57161c067e8f6e · discourse/discourse-activity-pub · GitHub
delay_minutes が 1 の場合、「1 minute」と表示されるべきです。

「投稿 #{%{post_number}} を公開し、%{minutes} 分後にグループアクターのフォロワーに配信します。」

discourse-activity-pub/config/locales/client.en.yml at a49ec5c4f5acac28bafbc1c57c57161c067e8f6e · discourse/discourse-activity-pub · GitHub
上記と同じです。

「トピック #%{topic_id} の公開されていない %{count} 件の投稿を公開します。投稿はグループアクターのフォロワーには配信されません。」

discourse-activity-pub/config/locales/client.en.yml at a49ec5c4f5acac28bafbc1c57c57161c067e8f6e · discourse/discourse-activity-pub · GitHub

公開されていない投稿が 1 件 の場合、「トピック #%{topic_id} の公開されていない %{count} 件の投稿を公開します。投稿はグループアクターのフォロワーには配信されません。」と言うべきです。

「%{min_length} から %{max_length} 文字、数字、ダッシュ、またはアンダースコア。」

discourse-activity-pub/config/locales/client.en.yml at a49ec5c4f5acac28bafbc1c57c57161c067e8f6e · discourse/discourse-activity-pub · GitHub
これは max_length に依存すると思います。max_length が 1 の場合、「letter, number, dash or underscore」と言うべきです。しかし、min_length も関連する他の言語があるかどうかはわかりません。

「ユーザー名は %{min_length} から %{max_length} 文字、数字、ダッシュ、またはアンダースコアである必要があります。」

discourse-activity-pub/config/locales/server.en.yml at a49ec5c4f5acac28bafbc1c57c57161c067e8f6e · discourse/discourse-activity-pub · GitHub
上記と同じです。

「このトピックの %{total} 件中 %{count} 件の投稿が公開されています。」

discourse-activity-pub/config/locales/client.en.yml at a49ec5c4f5acac28bafbc1c57c57161c067e8f6e · discourse/discourse-activity-pub · GitHub
これは counttotal の 2 つの変数に依存するため、少し複雑です。たとえば:

  • このトピックの 1 件中 1 件投稿 は公開されています
  • このトピックの 3 件中 1 件投稿 は公開されています
  • このトピックの 3 件中 2 件投稿 は公開されています
「いいね!」 4

遅れてすみません、Moin。これでほとんどの項目に対応できるはずです: DEV: Update pluralization for some strings by pmusaraj · Pull Request #262 · discourse/discourse-activity-pub · GitHub

これら2つについては、文字列はそのままにしておきます。ユーザー名が1文字に制限されているサイトは設定ミスです…変更する必要はありません。

「いいね!」 1

11文字のユーザー名を持つサイトについてはどうですか? 1と11で同じバージョンが使用される言語があります。また、英語で複数形を提供しない場合、複数の複数形を持つ言語ではどのように機能しますか?翻訳者はそれらの異なる複数形を入力できますか?

「いいね!」 1

これらの言語では、11は単数として扱われるのでしょうか?

「いいね!」 1

1 が付く数字に対して「1」のバージョンを使用する言語があります。(11が最良の例ではなかったかもしれません)。また、「1」と「その他」よりも多くのバージョンがあるため、1より大きい異なるカウントのみであっても、正確なカウントに基づいて異なる翻訳が必要になります。

ドイツ語はそのような言語ではありませんので、同僚の方が私よりも詳しいと思います。

「いいね!」 1

翻訳で少し苦労しています。Discourse は count または total に基づいて単数形と複数形を選択しますか?
私の理解では、通常は count です。
しかし、count が 1total が 3 の場合の処理方法がわかりません。「1 of 3 post in this topic is published」のようになります。「posts」を使用することで、「1 of 3 posts in this topic is published」と修正できます。しかし、その場合 total が 1 の場合は機能しません。:exploding_head:

この場合、Message Format support for localization が必要になるでしょうか?

それはエンジニア英語と呼ばれるものです。そのような形式は決して使用されるべきではありません。それは the/this post is published のようなものであるべきです。または、可能な場合は topic で、それに続く投稿は自動的に公開されます。

フィンランド語でも同様の状況で、数字の1(実際には0から9までのすべての数字)は数字を使用せずに書かれるべきです。しかし、かなり一般的な概念は、1 の代わりに one と書き、それより大きいものは数字です。

1 post のようなものは、英語を話す開発者が怠惰すぎて人間的なスタイルを使用しないため、常に運命づけられています。ほとんど声に出して言うのが申し訳ないほどです。そして、より一般的には:ヘッダー、テキストでこの方法を使用するよりもアメリカ的な方法と見なされます :smirking_face:

これは怠慢ではありません。数字のプレースホルダーを使用することは非常に重要です。上記で説明したように、たとえば「1 post」と言うのと同じように、「21 post」と言う言語もあります。英語のテキストで %{count} の代わりに「one」を使用した場合、翻訳者はそれを簡単に翻訳できますが、その結果、実際のカウントが21であるにもかかわらず、「one post」となってしまいます。
したがって、数字が使用されているのには理由があります。参照:Always use %{count} variable when translating pluralized strings

ちなみに、ドイツ語でも役立ちます。なぜなら、このような問題が回避されるからです。

コーディングが非常に低レベルで、%(count) = 1 の場合に %(count) を単語に置き換えることが不可能であるとは、信じがたいです。ローカライズで単数形と複数形で異なるオプションが提供されている場合、そのようなプレースホルダーをプレーンテキストに変更したと確信しています。

これが、私が怠惰とエンジニア英語について言っていることです。内部的には変数とプレースホルダーを使用する必要がありますが、それらは人間が読めるネイティブな形式に変換されるべきです。結局のところ、ソフトウェアを使用しているのは、エンジニアではなく、一般のユーザーなのですから…

ええ、わかっています。これは、1 of 3…1 of 1… をどのように翻訳するかを検討するよりも、はるかに広範で大きな問題です。しかし、私の最も深い点は、そのようなことを不思議に思う必要はないということです(他の無数の言語の違いはさておき)。

しかし、確かに、複雑なAIが存在する世界に住んでいるかもしれませんが、1 of 1 のような状況を回避する解決策はないのかもしれません :joy:

これらのテキストの単数形と複数形を任意の方法で持つことができるというトピックから大きく外れています。

しかし、おそらくインターフェース全体で 1 をすべて「one」に置き換えることができるでしょう。
ただし、ドイツ語ではそれほど簡単にはいきません。問題は、ドイツ語では「one」という単語が格、性、文法上の役割によって変化することです。

例:

  • The topic will remain open for one month. → Das Thema ist noch einen Monat geöffnet。
  • The topic will be closed in one month. → Das Thema wird in einem Monat geschlossen。
  • One month has passed. → Ein Monat ist vergangen。

したがって、ドイツ語では数字を単語で書くことも一般的ですが、これを正しく処理することは文法的に複雑です。
数字の「1」を単語の「eins」に置き換えるだけではうまくいきません。なぜなら、その形式は名詞の前に決して使用されず、正しい単語の形式は文法的な格に依存するからです。

つまり、数字の代わりに単語を使用すると、翻訳者にとってより多くの作業が発生します。
「one month」、「one week」、「one day」などに展開される %{duration} のようなプレースホルダーをすべての文脈で単純に使用することはできません。
3つの期間と3つの文の代わりに、文法的な組み合わせごとに個別のバージョンが必要になります。これにより、テキスト量が数倍になる可能性があります。

「いいね!」 1

リンクありがとうございます。コードを読んだり、アラビア語のような他の言語を見たりすると、たとえ英語の文字列がバリアント間で同じであっても、言語は独自のオーバーライドを提供できることがわかります。たとえば、アラビア語には数が2の場合に別のルールがあり、英語では定義されていない文字列で two: が使用されているのを確認しました。したがって、1/11の場合、ルールを持つ言語はそのバリアントを提供できます。私の知る限り、英語で定義する必要はありません。

この件について調べていただきありがとうございます。この文字列のコンテキストはわかりませんが、変更を加えてPRを提出したい場合は、喜んで確認します。ありがとうございます。

Crowdinでこれをどのように行うことができますか?
アラビア語にdiscourse_activity_pub.actor.warning.invalid_usernameを翻訳しようとすると、Crowdinで次のように表示されます。

以前、複数形を入力するメニューを見たことがあります。たとえば、js.user.password.too_short

しかし、私の経験では、複数形が英語でも定義されている場合にのみ、これらの異なるバージョンを追加できます。

私もです。最後にActivityPubのテキストを確認したのは、このトピックを作成した4月でした。今回は、単にプレースホルダーを翻訳中に置き換えていました。そうしないと、単語を選択するのが非常に難しいためです。「このトピックの1/3の投稿が公開されています」が、ドイツ語だけでなく英語でも間違っているように見えたことに気づきました。