Add API function for formatting lists

Exactly how robust across languages this is remains unknown.
It may be best to use it only for simple lists.

The API is exposed to Lua as well.
This commit is contained in:
Celtic Minstrel 2017-05-21 23:47:19 -04:00
parent 021d9653c5
commit 2cc7ec4bde
3 changed files with 65 additions and 0 deletions

View file

@ -13,6 +13,8 @@
See the COPYING file for more details.
*/
#define GETTEXT_DOMAIN "wesnoth-lib"
#include "formula/string_utils.hpp"
#include "config.hpp"
@ -240,6 +242,42 @@ t_string interpolate_variables_into_tstring(const t_string &tstr, const variable
return tstr;
}
std::string format_conjunct_list(const t_string& empty, const std::vector<t_string>& elems) {
switch(elems.size()) {
case 0: return empty;
case 1: return elems[0];
// TRANSLATORS: Formats a two-element conjunctive list.
case 2: return VGETTEXT("conjunct pair^$first and $second", {{"first", elems[0]}, {"second", elems[1]}});
}
// TRANSLATORS: Formats the first two elements of a conjunctive list.
std::string prefix = VGETTEXT("conjunct start^$first, $second", {{"first", elems[0]}, {"second", elems[1]}});
// For size=3 this loop is not entered
for(size_t i = 2; i < elems.size() - 1; i++) {
// TRANSLATORS: Formats successive elements of a conjunctive list.
prefix = VGETTEXT("conjunct mid^$prefix, $next", {{"prefix", prefix}, {"next", elems[i]}});
}
// TRANSLATORS: Formats the final element of a conjunctive list.
return VGETTEXT("conjunct end^$prefix, and $last", {{"prefix", prefix}, {"last", elems.back()}});
}
std::string format_disjunct_list(const t_string& empty, const std::vector<t_string>& elems) {
switch(elems.size()) {
case 0: return empty;
case 1: return elems[0];
// TRANSLATORS: Formats a two-element disjunctive list.
case 2: return VGETTEXT("disjunct pair^$first or $second", {{"first", elems[0]}, {"second", elems[1]}});
}
// TRANSLATORS: Formats the first two elements of a disjunctive list.
std::string prefix = VGETTEXT("disjunct start^$first, $second", {{"first", elems[0]}, {"second", elems[1]}});
// For size=3 this loop is not entered
for(size_t i = 2; i < elems.size() - 1; i++) {
// TRANSLATORS: Formats successive elements of a disjunctive list.
prefix = VGETTEXT("disjunct mid^$prefix, $next", {{"prefix", prefix}, {"next", elems[i]}});
}
// TRANSLATORS: Formats the final element of a disjunctive list.
return VGETTEXT("disjunct end^$prefix, or $last", {{"prefix", prefix}, {"last", elems.back()}});
}
}
std::string vgettext(const char *msgid, const utils::string_map& symbols)

View file

@ -51,6 +51,22 @@ std::string interpolate_variables_into_string(const std::string &str, const vari
*/
t_string interpolate_variables_into_tstring(const t_string &str, const variable_set& variables);
/**
* Format a conjunctive list.
* @param empty The string to return for an empty list
* @param elems The list of entries in the list
* @return The elements of the list joined by "and".
*/
std::string format_conjunct_list(const t_string& empty, const std::vector<t_string>& elems);
/**
* Format a disjunctive list.
* @param empty The string to return for an empty list
* @param elems The list of entries in the list
* @return The elements of the list joined or "and".
*/
std::string format_disjunct_list(const t_string& empty, const std::vector<t_string>& elems);
}
/** Handy wrappers around interpolate_variables_into_string and gettext. */

View file

@ -318,6 +318,15 @@ static int intf_format(lua_State* L)
return 1;
}
template<bool conjunct>
static int intf_format_list(lua_State* L)
{
const t_string empty = luaW_checktstring(L, 1);
auto values = lua_check<std::vector<t_string>>(L, 2);
lua_push(L, (conjunct ? utils::format_conjunct_list : utils::format_disjunct_list)(empty, values));
return 1;
}
// End Callback implementations
// Template which allows to push member functions to the lua kernel base into lua as C functions, using a shim
@ -447,6 +456,8 @@ lua_kernel_base::lua_kernel_base()
{ "get_image_size", &intf_get_image_size },
{ "get_time_stamp", &intf_get_time_stamp },
{ "format", &intf_format },
{ "format_conjunct_list", &intf_format_list<true> },
{ "format_disjunct_list", &intf_format_list<false> },
{ nullptr, nullptr }
};