[boost.locale] linguistic case discrimination in translation

Hello Users, I like to join two translation into a single one using the word 'and' if the code path require it, e.g. translation 1 is: "{1} error" and translation 2 is: "{1} warning" if the relevant err/warn counter are both != 0 I want to combine this statement using the mentioned 'and'. I guess, an example teels more than this here: see https://wandbox.org/permlink/HbnCLQKhHAb3eqZr or even on bottom. Line 89 ... 94 looks too complicated to me even for the translator which need an own context of the intend. I've seen a lot of dating formating flags, but nothings useful for my use case. BTW; does boost.locate still using auto_ptr? I had to add the option '-Wno-deprecated' to rid the warnings... Thanks, Olaf -----------------------8<-------------------------- #include <iostream> #include <boost/locale.hpp> struct context { std::size_t error_count; std::size_t warning_count; context() : error_count{ 0 } , warning_count{ 0 } { } }; struct failure_status { context const& ctx; failure_status(context const& ctx_) : ctx{ ctx_ } { } std::ostream& operator()(std::ostream& os) const; }; static inline std::ostream& operator<<(std::ostream& os, failure_status const& status) { return status(os); } namespace detail { struct error_message { std::size_t const count; explicit error_message(std::size_t count_) : count{ count_ } { } std::ostream& operator()(std::ostream& os) const { using boost::locale::format; using boost::locale::translate; if(count) { os << format(translate( "{1} error", "{1} errors", count)) % count ; } return os; } }; std::ostream& operator<<(std::ostream& os, error_message const& err_msg) { return err_msg(os); } struct warning_message { std::size_t const count; explicit warning_message(std::size_t count_) : count{ count_ } { } std::ostream& operator()(std::ostream& os) const { using boost::locale::format; using boost::locale::translate; if(count) { os << format(translate( "{1} warning", "{1} warnings", count)) % count ; } return os; } }; std::ostream& operator<<(std::ostream& os, warning_message const& warn_msg) { return warn_msg(os); } } // namespace detail std::ostream& failure_status::operator()(std::ostream& os) const { using detail::warning_message; using detail::error_message; using boost::locale::translate; bool const any_failure = [&] { return ctx.error_count || ctx.warning_count; }(); if(any_failure) { os << error_message(ctx.error_count); if(ctx.warning_count) { os << translate(" and "); // poor translator ... } os << warning_message(ctx.warning_count); os << translate(" generated."); } return os; } int main() { context ctx; ctx.error_count = 1; ctx.warning_count = 42; std::cout << failure_status(ctx) << "\n"; } ----------------------->8--------------------------

Am 17.08.2018 um 08:21 schrieb Olaf Peter via Boost-users:
Hello Users,
I like to join two translation into a single one using the word 'and' if the code path require it, e.g.
translation 1 is: "{1} error" and translation 2 is: "{1} warning"
if the relevant err/warn counter are both != 0 I want to combine this statement using the mentioned 'and'. I guess, an example teels more than this here:
see https://wandbox.org/permlink/HbnCLQKhHAb3eqZr or even on bottom.
Line 89 ... 94 looks too complicated to me even for the translator which need an own context of the intend.
to make it clear - the best solution would be to have a single format(translate("")) statement.

On 17/08/2018 18:21, Olaf Peter wrote:
I like to join two translation into a single one using the word 'and' if the code path require it, e.g. translation 1 is: "{1} error" and translation 2 is: "{1} warning" > if the relevant err/warn counter are both != 0 I want to combine this statement using the mentioned 'and'. I guess, an example teels more than this here: > see https://wandbox.org/permlink/HbnCLQKhHAb3eqZr or even on bottom.
Line 89 ... 94 looks too complicated to me even for the translator which need an own context of the intend. One of the cardinal rules of translation is to not translate fragments, since different languages can have different sentence structures and word orderings.
So you should probably print exactly one of: - format(translate("{1} generated.")) % error_message - format(translate("{1} generated.")) % warning_message - format(translate("{1} and {2} generated.")) % error_message % warning_message If you're not using your error_message generation elsewhere you should have the entire thing inlined in here rather than trying to factor it out. Factoring out "common" sentence fragments rarely ends well. Even the cases above where it appears that the format string for warnings and errors is the same, ideally should not use a common constant (although it is unavoidable in this case, unless you do inline it all so that they become unique), since it's plausible that some language might require the word 'generated' to have different emphasis depending on whether it is referring to warnings or errors. Note how the example of the plural-form translate in https://www.boost.org/doc/libs/1_67_0/libs/locale/doc/html/messages_formatti... translates the entire string, even though it apparently has many words in common in English.
participants (2)
-
Gavin Lambert
-
Olaf Peter