24 #include <boost/algorithm/string/trim.hpp>
39 if(lua_isstring(L, 1)) {
40 std::string str = lua_tostring(L, 1);
54 template<
bool conjunct>
58 auto values = lua_check<std::vector<t_string>>(L, 2);
68 if(lua_type(L, 2) == LUA_TSTRING) {
70 lua_getglobal(L,
"stringx");
74 }
else if(lua_type(L, 2) == LUA_TNUMBER) {
76 int len = lua_rawlen(L, 1);
77 int i = luaL_checkinteger(L, 2);
79 if(
i == 0 || abs(
i) > len) {
102 enum {BASIC, ESCAPED, PAREN, ANIM}
type = BASIC;
103 const std::string& str = luaL_checkstring(L, 1);
104 const std::string& sep = luaL_optstring(L, 2,
",");
105 std::string left, right;
107 if(lua_istable(L, 3)) {
118 return luaL_error(L,
"escape and expand_anim options are incompatible!");
121 left = luaL_checkstring(L, -1);
122 if(left.size() != 1) {
123 return luaL_error(L,
"escape must be a single character");
126 left = right = luaL_checkstring(L, -1);
130 right.push_back(
']');
133 left = luaL_checkstring(L, -2);
134 right = luaL_checkstring(L, -1);
136 if(left.find_first_of(
"[]") != std::string::npos || right.find_first_of(
"[]") != std::string::npos) {
137 return luaL_error(L,
"left and right cannot include square brackets [] if expand_anim is enabled");
141 right.push_back(
']');
148 if(
type != ESCAPED && left.size() != right.size()) {
149 return luaL_error(L,
"left and right need to be strings of the same length");
177 const std::string& str = luaL_checkstring(L, 1);
178 const std::string& left = luaL_optstring(L, 2,
"(");
179 const std::string& right = luaL_optstring(L, 3,
")");
180 if(left.size() != right.size()) {
181 return luaL_error(L,
"left and right need to be strings of the same length");
196 const std::string& str = luaL_checkstring(L, 1);
197 const std::string& sep = luaL_optstring(L, 2,
",");
198 const std::string& kv = luaL_optstring(L, 3,
":");
200 if(sep.size() != 1) {
201 return luaL_error(L,
"separator must be a single character");
204 return luaL_error(L,
"key_value_separator must be a single character");
207 if(lua_istable(L, 4)) {
216 dflt = luaL_checkstring(L, -1);
234 if(lua_istable(L, 1)) {
236 sep = luaL_optstring(L, 2,
",");
237 }
else if(lua_istable(L, 2)) {
238 sep = luaL_checkstring(L, 1);
240 }
else return luaL_error(L,
"invalid arguments to join, should have map and separator");
241 std::vector<std::string> pieces;
242 for(
int i = 1;
i <= luaL_len(L, list_idx);
i++) {
243 lua_getglobal(L,
"tostring");
244 lua_geti(L, list_idx,
i);
246 pieces.push_back(luaL_checkstring(L, -1));
265 if(lua_istable(L, 1)) {
267 sep = luaL_optstring(L, 2,
",");
268 kv = luaL_optstring(L, 3,
":");
269 }
else if(lua_istable(L, 2)) {
270 sep = luaL_checkstring(L, 1);
272 kv = luaL_optstring(L, 3,
":");
273 }
else if(lua_istable(L, 3)) {
274 sep = luaL_checkstring(L, 1);
275 kv = luaL_checkstring(L, 2);
277 }
else return luaL_error(L,
"invalid arguments to join_map, should have map, separator, and key_value_separator");
278 std::map<std::string, std::string> pieces;
279 for(lua_pushnil(L); lua_next(L, map_idx); ) {
280 int key_idx = lua_absindex(L, -2), val_idx = lua_absindex(L, -1);
281 lua_getglobal(L,
"tostring");
282 lua_pushvalue(L, key_idx);
284 std::string& val = pieces[luaL_checkstring(L, -1)];
285 lua_getglobal(L,
"tostring");
286 lua_pushvalue(L, val_idx);
288 val = luaL_checkstring(L, -1);
289 lua_settop(L, key_idx);
300 std::string str = luaL_checkstring(L, 1);
302 lua_pushlstring(L, str.c_str(), str.size());
309 int nargs = lua_gettop(L);
312 lua_getglobal(L,
"tostring");
319 lua_pushvalue(L, lua_upvalueindex(1));
323 lua_call(L, nargs, 1);
334 const std::string str = luaL_checkstring(L, 1);
335 if(luaL_opt(L, lua_toboolean, 2,
false)) {
337 lua_pushnumber(L, interval.first);
338 lua_pushnumber(L, interval.second);
341 lua_pushinteger(L, interval.first);
342 lua_pushinteger(L, interval.second);
348 auto& lk = lua_kernel_base::get_lua_kernel<lua_kernel_base>(L);
349 lk.add_log(
"Adding stringx module...\n");
350 static luaL_Reg
const str_callbacks[] = {
359 {
"format_conjunct_list", &intf_format_list<true> },
360 {
"format_disjunct_list", &intf_format_list<false> },
361 {
nullptr,
nullptr },
364 luaL_setfuncs(L, str_callbacks, 0);
366 lua_createtable(L, 0, 1);
367 lua_getglobal(L,
"string");
368 lua_setfield(L, -2,
"__index");
369 lua_setmetatable(L, -2);
372 lua_pushliteral(L,
"");
373 lua_getmetatable(L, -1);
375 lua_setfield(L, -2,
"__index");
376 lua_setmetatable(L, -2);
380 lua_getglobal(L,
"string");
381 lua_getfield(L, -1,
"format");
383 lua_setfield(L, -2,
"format");
A config object defines a single node in a WML file, with access to child nodes.
bool luaW_iststring(lua_State *L, int index)
config luaW_checkconfig(lua_State *L, int index)
Converts an optional table or vconfig to a config object.
bool luaW_toboolean(lua_State *L, int n)
bool luaW_tableget(lua_State *L, int index, const char *key)
bool luaW_getglobal(lua_State *L, const std::vector< std::string > &path)
Pushes the value found by following the variadic names (char *), if the value is not nil.
t_string luaW_checktstring(lua_State *L, int index)
Converts a scalar to a translatable string.
static int intf_str_split(lua_State *L)
Splits a string into parts according to options Arg 1: String to split Arg 2: Separator Arg 3: Option...
static int intf_str_map_split(lua_State *L)
Splits a string into a map Arg 1: string to split Arg 2: Separator for items Arg 3: Separator for key...
static int intf_parse_range(lua_State *L)
Parses a range string of the form a-b into an interval pair Accepts the string "infinity" as represen...
static int intf_format(lua_State *L)
Formats a message by interpolating WML variable syntax Arg 1: (optional) Logger Arg 2: Message.
static int intf_str_paren_split(lua_State *L)
Splits a string into parenthesized portions and portions between parenthesized portions Arg 1: String...
static int intf_format_list(lua_State *L)
Formats a list into human-readable format Arg 1: default value, used if the list is empty Arg 2: list...
static int intf_str_trim(lua_State *L)
Trims whitespace from the beginning and end of a string.
static int impl_str_index(lua_State *L)
Enables indexing a string by an integer, while also treating the stringx module as its metatable....
static int intf_str_join(lua_State *L)
Joins a list into a string; calls __tostring and __index metamethods Arg 1: list to join Arg 2: separ...
static int intf_str_format(lua_State *L)
static int intf_str_join_map(lua_State *L)
Joins a map into a string; calls __tostring metamethods (on both key and value) but not __index Arg 1...
int luaW_open(lua_State *L)
@ STRIP_SPACES
REMOVE_EMPTY: remove empty elements.
void trim(std::string_view &s)
std::string interpolate_variables_into_string(const std::string &str, const string_map *const symbols)
Function which will interpolate variables, starting with '$' in the string 'str' with the equivalent ...
std::map< std::string, std::string > map_split(const std::string &val, char major, char minor, int flags, const std::string &default_value)
Splits a string based on two separators into a map.
std::vector< std::string > quoted_split(const std::string &val, char c, int flags, char quote)
This function is identical to split(), except it does not split when it otherwise would if the previo...
std::string join_map(const T &v, const std::string &major=",", const std::string &minor=":")
std::pair< int, int > parse_range(const std::string &str)
Recognises the following patterns, and returns a {min, max} pair.
std::vector< std::string > parenthetical_split(const std::string &val, const char separator, const std::string &left, const std::string &right, const int flags)
Splits a string based either on a separator, except then the text appears within specified parenthesi...
t_string interpolate_variables_into_tstring(const t_string &tstr, const variable_set &variables)
Function that does the same as the above, for t_stringS.
std::string format_disjunct_list(const t_string &empty, const std::vector< t_string > &elems)
Format a disjunctive list.
std::vector< std::string > square_parenthetical_split(const std::string &val, const char separator, const std::string &left, const std::string &right, const int flags)
Similar to parenthetical_split, but also expands embedded square brackets.
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
std::string format_conjunct_list(const t_string &empty, const std::vector< t_string > &elems)
Format a conjunctive list.
std::vector< std::string > split(const config_attribute_value &val)
std::pair< double, double > parse_range_real(const std::string &str)
Recognises similar patterns to parse_range, and returns a {min, max} pair.
void lua_push(lua_State *L, const T &val)
std::decay_t< T > luaW_table_get_def(lua_State *L, int index, std::string_view k, const T &def)
returns t[k] where k is the table at index index and k is k or def if it is not convertible to the co...