From 2a150049c6fb83ae4d83941fcd1ca223716c9c57 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 24 Oct 2024 19:04:02 +0300 Subject: [PATCH 01/14] fix world-generator.md --- doc/en/world-generator.md | 18 ++++++++---------- doc/ru/world-generator.md | 18 ++++++++---------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/doc/en/world-generator.md b/doc/en/world-generator.md index 0de466bb..15d9ea54 100644 --- a/doc/en/world-generator.md +++ b/doc/en/world-generator.md @@ -72,15 +72,13 @@ Fragments used by the generator must present in the directory: ## Structures -A structure is a set of rules for inserting a fragment into the world by the generator. It currently has no properties, being created as empty objects in the `generators/generator_name.files/structures.json` file. Example: -```lua -{ - "tree0": {}, - "tree1": {}, - "tree2": {}, - "tower": {}, - "coal_ore0": {} -} +A structure is a set of rules for inserting a fragment into the world by the generator. It currently has no properties, being created as empty objects in the `generators/generator_name.files/structures.toml` file. Example: +```toml +tree0 = {} +tree1 = {} +tree2 = {} +tower = {} +coal_ore0 = {} ``` Currently, the name of the structure must match the name of the fragment used. @@ -136,7 +134,7 @@ structures = [ - block - plant block - structure-chance - probability of generating a small structure on a surface block. - structures - structures randomly placed on the surface. - - name - name of the structure declared in `structures.json`. + - name - name of the structure declared in `structures.toml`. - weight - weight directly affecting the chance of choosing a specific structure. ### Biome Parameters diff --git a/doc/ru/world-generator.md b/doc/ru/world-generator.md index ec3112cb..98be0ff4 100644 --- a/doc/ru/world-generator.md +++ b/doc/ru/world-generator.md @@ -72,15 +72,13 @@ ## Структуры -Структура - набор правил по вставке фрагмента в мир генератором. На данный момент не имеет свойств, создаваясь в виде пустых объектов в файле `generators/имя_генератора.files/structures.json`. Пример: -```lua -{ - "tree0": {}, - "tree1": {}, - "tree2": {}, - "tower": {}, - "coal_ore0": {} -} +Структура - набор правил по вставке фрагмента в мир генератором. На данный момент не имеет свойств, создаваясь в виде пустых объектов в файле `generators/имя_генератора.files/structures.toml`. Пример: +```toml +tree0 = {} +tree1 = {} +tree2 = {} +tower = {} +coal_ore0 = {} ``` На данный момент, имя структуры должно совпадать с именем использованного фрагмента. @@ -136,7 +134,7 @@ structures = [ - block - блок растения - structure-chance - вероятность генерации малой структуры на блоке поверхности. - structures - структуры, случайно расставляемые на поверхности. - - name - имя структуры, объявленной в `structures.json`. + - name - имя структуры, объявленной в `structures.toml`. - weight - вес, напрямую влияющий на шанс выбора конкретной структуры. ### Параметры биомов From 6964a186050409a6c8d9cb0220a915eb3664ac3a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 25 Oct 2024 13:58:17 +0300 Subject: [PATCH 02/14] add platform::open_folder --- src/util/platform.cpp | 20 ++++++++++++++++---- src/util/platform.hpp | 6 +++++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/util/platform.cpp b/src/util/platform.cpp index b749718d..b1c5362c 100644 --- a/src/util/platform.cpp +++ b/src/util/platform.cpp @@ -7,12 +7,11 @@ #include #include "typedefs.hpp" +#include "stringutil.hpp" #ifdef _WIN32 #include -#include "stringutil.hpp" - void platform::configure_encoding() { // set utf-8 encoding to console output SetConsoleOutputCP(CP_UTF8); @@ -35,7 +34,6 @@ std::string platform::detect_locale() { .replace(2, 1, "_") .substr(0, 5); } - #else void platform::configure_encoding() { @@ -49,5 +47,19 @@ std::string platform::detect_locale() { return preferredLocaleName.substr(0, 5); } - #endif + + +void platform::open_folder(const std::filesystem::path& folder) { + if (!std::filesystem::is_directory(folder)) { + return; + } +#ifdef __APPLE__ + auto cmd = "open "+util::quote(folder.u8string()); +#elif defined(_WIN32) + auto cmd = "start "+util::quote(folder.u8string()); +#else + auto cmd = "xdg-open "+util::quote(folder.u8string()); +#endif + system(cmd.c_str()); +} diff --git a/src/util/platform.hpp b/src/util/platform.hpp index a620acad..973c0ebd 100644 --- a/src/util/platform.hpp +++ b/src/util/platform.hpp @@ -1,9 +1,13 @@ #pragma once #include +#include namespace platform { void configure_encoding(); - // @return environment locale in ISO format ll_CC + /// @return environment locale in ISO format ll_CC std::string detect_locale(); + /// @brief Open folder using system file manager application + /// @param folder target folder + void open_folder(const std::filesystem::path& folder); } From 751cde750345d9505283535e3bf506f7abcd19d7 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 25 Oct 2024 14:07:32 +0300 Subject: [PATCH 03/14] add core.open_folder --- src/logic/scripting/lua/libs/libcore.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/logic/scripting/lua/libs/libcore.cpp b/src/logic/scripting/lua/libs/libcore.cpp index 6f0dd8b8..b0a960b2 100644 --- a/src/logic/scripting/lua/libs/libcore.cpp +++ b/src/logic/scripting/lua/libs/libcore.cpp @@ -167,6 +167,14 @@ static int l_get_setting_info(lua::State* L) { throw std::runtime_error("unsupported setting type"); } +#include "util/platform.hpp" + +static int l_open_folder(lua::State* L) { + auto path = engine->getPaths()->resolve(lua::require_string(L, 1)); + platform::open_folder(path); + return 0; +} + /// @brief Quit the game static int l_quit(lua::State*) { Window::setShouldClose(true); @@ -184,5 +192,6 @@ const luaL_Reg corelib[] = { {"set_setting", lua::wrap}, {"str_setting", lua::wrap}, {"get_setting_info", lua::wrap}, + {"open_folder", lua::wrap}, {"quit", lua::wrap}, {NULL, NULL}}; From 74b9dd6d2f7fb7e5ad6b47bf4f36382648544389 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 25 Oct 2024 14:26:59 +0300 Subject: [PATCH 04/14] update platform.cpp --- src/util/platform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/platform.cpp b/src/util/platform.cpp index b1c5362c..2a19a39b 100644 --- a/src/util/platform.cpp +++ b/src/util/platform.cpp @@ -57,7 +57,7 @@ void platform::open_folder(const std::filesystem::path& folder) { #ifdef __APPLE__ auto cmd = "open "+util::quote(folder.u8string()); #elif defined(_WIN32) - auto cmd = "start "+util::quote(folder.u8string()); + auto cmd = "explorer "+util::quote(folder.u8string()); #else auto cmd = "xdg-open "+util::quote(folder.u8string()); #endif From 87e3247ecf3fe37b06ea23dc40b297a09e27a13e Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 25 Oct 2024 14:43:31 +0300 Subject: [PATCH 05/14] update platform.cpp --- src/util/platform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/platform.cpp b/src/util/platform.cpp index 2a19a39b..8956abd7 100644 --- a/src/util/platform.cpp +++ b/src/util/platform.cpp @@ -57,7 +57,7 @@ void platform::open_folder(const std::filesystem::path& folder) { #ifdef __APPLE__ auto cmd = "open "+util::quote(folder.u8string()); #elif defined(_WIN32) - auto cmd = "explorer "+util::quote(folder.u8string()); + auto cmd = "start explorer "+util::quote(folder.u8string()); #else auto cmd = "xdg-open "+util::quote(folder.u8string()); #endif From df31b9e589c0bccebbc0d19cfab6d52dfc821bb6 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 25 Oct 2024 14:46:18 +0300 Subject: [PATCH 06/14] update platform::open_folder docs --- src/util/platform.cpp | 1 - src/util/platform.hpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/util/platform.cpp b/src/util/platform.cpp index 8956abd7..6bc3b343 100644 --- a/src/util/platform.cpp +++ b/src/util/platform.cpp @@ -49,7 +49,6 @@ std::string platform::detect_locale() { } #endif - void platform::open_folder(const std::filesystem::path& folder) { if (!std::filesystem::is_directory(folder)) { return; diff --git a/src/util/platform.hpp b/src/util/platform.hpp index 973c0ebd..b6e8bde9 100644 --- a/src/util/platform.hpp +++ b/src/util/platform.hpp @@ -7,7 +7,7 @@ namespace platform { void configure_encoding(); /// @return environment locale in ISO format ll_CC std::string detect_locale(); - /// @brief Open folder using system file manager application + /// @brief Open folder using system file manager asynchronously /// @param folder target folder void open_folder(const std::filesystem::path& folder); } From e6ad3e41a6ae0c797382a260e2058a1284ba01d9 Mon Sep 17 00:00:00 2001 From: taksilia <102991859+taksilia@users.noreply.github.com> Date: Fri, 25 Oct 2024 16:10:06 +0300 Subject: [PATCH 07/14] A typo has been fixed --- doc/ru/scripting/builtins/libpack.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ru/scripting/builtins/libpack.md b/doc/ru/scripting/builtins/libpack.md index 0beb0667..543ea7a3 100644 --- a/doc/ru/scripting/builtins/libpack.md +++ b/doc/ru/scripting/builtins/libpack.md @@ -31,7 +31,7 @@ file.write(pack.shared_file(PACK_ID, "example.txt"), text) ``` Для пака *containermod* запишет текст в файл `config:containermod/example.txt` -Используйте для хранения данныхm общих для всех миров. +Используйте для хранения данных общих для всех миров. ```python pack.get_folder(packid: str) -> str From 52e62bbf9573d23729e61c307a0fabc2a549d828 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 25 Oct 2024 17:22:54 +0300 Subject: [PATCH 08/14] add utf8.encode --- src/logic/scripting/lua/libs/api_lua.hpp | 1 + src/logic/scripting/lua/libs/libutf8.cpp | 28 ++++++++++++++++++++++++ src/logic/scripting/lua/lua_engine.cpp | 1 + 3 files changed, 30 insertions(+) create mode 100644 src/logic/scripting/lua/libs/libutf8.cpp diff --git a/src/logic/scripting/lua/libs/api_lua.hpp b/src/logic/scripting/lua/libs/api_lua.hpp index 2ac9c1e8..f9c8b3f8 100644 --- a/src/logic/scripting/lua/libs/api_lua.hpp +++ b/src/logic/scripting/lua/libs/api_lua.hpp @@ -35,6 +35,7 @@ extern const luaL_Reg playerlib[]; extern const luaL_Reg quatlib[]; // quat.cpp extern const luaL_Reg timelib[]; extern const luaL_Reg tomllib[]; +extern const luaL_Reg utf8lib[]; extern const luaL_Reg vec2lib[]; // vecn.cpp extern const luaL_Reg vec3lib[]; // vecn.cpp extern const luaL_Reg vec4lib[]; // vecn.cpp diff --git a/src/logic/scripting/lua/libs/libutf8.cpp b/src/logic/scripting/lua/libs/libutf8.cpp new file mode 100644 index 00000000..792f2513 --- /dev/null +++ b/src/logic/scripting/lua/libs/libutf8.cpp @@ -0,0 +1,28 @@ +#include "api_lua.hpp" + +#include + +#include "../lua_custom_types.hpp" +#include "util/stringutil.hpp" + +int l_encode(lua::State* L) { + std::string string = lua::require_string(L, 1); + if (lua::toboolean(L, 2)) { + lua::createtable(L, string.length(), 0); + for (size_t i = 0; i < string.length(); i++) { + lua::pushinteger(L, string[i]); + lua::rawseti(L, i+1); + } + } else { + lua::newuserdata(L, string.length()); + auto bytearray = lua::touserdata(L, -1); + bytearray->data().reserve(string.length()); + std::memcpy(bytearray->data().data(), string.data(), string.length()); + } + return 1; +} + +const luaL_Reg utf8lib[] = { + {"encode", lua::wrap}, + {NULL, NULL} +}; diff --git a/src/logic/scripting/lua/lua_engine.cpp b/src/logic/scripting/lua/lua_engine.cpp index fd40e612..fe3e75b5 100644 --- a/src/logic/scripting/lua/lua_engine.cpp +++ b/src/logic/scripting/lua/lua_engine.cpp @@ -51,6 +51,7 @@ static void create_libs(State* L, StateType stateType) { openlib(L, "quat", quatlib); openlib(L, "time", timelib); openlib(L, "toml", tomllib); + openlib(L, "utf8", utf8lib); openlib(L, "vec2", vec2lib); openlib(L, "vec3", vec3lib); openlib(L, "vec4", vec4lib); From 52ed1abf1c9d1d56fc9610d5d67d476ee2efbc2d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 25 Oct 2024 22:56:11 +0300 Subject: [PATCH 09/14] add utf8.decode --- src/logic/scripting/lua/libs/libutf8.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/logic/scripting/lua/libs/libutf8.cpp b/src/logic/scripting/lua/libs/libutf8.cpp index 792f2513..4cfedd03 100644 --- a/src/logic/scripting/lua/libs/libutf8.cpp +++ b/src/logic/scripting/lua/libs/libutf8.cpp @@ -5,7 +5,7 @@ #include "../lua_custom_types.hpp" #include "util/stringutil.hpp" -int l_encode(lua::State* L) { +static int l_encode(lua::State* L) { std::string string = lua::require_string(L, 1); if (lua::toboolean(L, 2)) { lua::createtable(L, string.length(), 0); @@ -22,7 +22,25 @@ int l_encode(lua::State* L) { return 1; } +static int l_decode(lua::State* L) { + if (lua::istable(L, 1)) { + size_t size = lua::objlen(L, 1); + util::Buffer buffer(size); + return lua::pushstring(L, std::string(buffer.data(), size)); + } else if (auto bytes = lua::touserdata(L, 1)) { + return lua::pushstring( + L, + std::string( + reinterpret_cast(bytes->data().data()), + bytes->data().size() + ) + ); + } + return 1; +} + const luaL_Reg utf8lib[] = { {"encode", lua::wrap}, + {"decode", lua::wrap}, {NULL, NULL} }; From f3181dee88500a130fe5b6b5f66a8c55f92798d9 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 26 Oct 2024 10:31:45 +0300 Subject: [PATCH 10/14] add util::length_utf8 --- src/util/stringutil.cpp | 12 +++++++++++- src/util/stringutil.hpp | 5 +++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/util/stringutil.cpp b/src/util/stringutil.cpp index c104bd5e..12936343 100644 --- a/src/util/stringutil.cpp +++ b/src/util/stringutil.cpp @@ -128,7 +128,7 @@ inline uint utf8_len(ubyte cp) { if ((cp & 0xF8) == 0xF0) { return 4; } - return 0; + throw std::runtime_error("utf8 decode error"); } uint32_t util::decode_utf8(uint& size, const char* chr) { @@ -156,6 +156,16 @@ size_t util::crop_utf8(std::string_view s, size_t maxSize) { return pos; } +size_t util::length_utf8(std::string_view s) { + size_t length = 0; + size_t pos = 0; + while (pos < s.length()) { + pos += utf8_len(s[pos]); + length++; + } + return length; +} + template std::string xstr2str_utf8(const std::basic_string& xs) { std::vector chars; diff --git a/src/util/stringutil.hpp b/src/util/stringutil.hpp index c7bc2fb5..f584a53c 100644 --- a/src/util/stringutil.hpp +++ b/src/util/stringutil.hpp @@ -44,6 +44,11 @@ namespace util { /// @param maxSize max encoded string length after crop /// @return cropped string size (less or equal to maxSize) size_t crop_utf8(std::string_view s, size_t maxSize); + + /// @brief Measure utf8-encoded string length + /// @param s source encoded string + /// @return unicode string length (number of codepoints) + size_t length_utf8(std::string_view s); bool is_integer(const std::string& text); bool is_integer(const std::wstring& text); From 3dc334e778262a6c7f7614a62c78e27e2d4cc5d3 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 26 Oct 2024 10:32:34 +0300 Subject: [PATCH 11/14] add utf8.length, utf8.codepoint --- src/logic/scripting/lua/libs/libutf8.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/logic/scripting/lua/libs/libutf8.cpp b/src/logic/scripting/lua/libs/libutf8.cpp index 4cfedd03..80af5d5d 100644 --- a/src/logic/scripting/lua/libs/libutf8.cpp +++ b/src/logic/scripting/lua/libs/libutf8.cpp @@ -6,11 +6,11 @@ #include "util/stringutil.hpp" static int l_encode(lua::State* L) { - std::string string = lua::require_string(L, 1); + std::string_view string = lua::require_string(L, 1); if (lua::toboolean(L, 2)) { lua::createtable(L, string.length(), 0); for (size_t i = 0; i < string.length(); i++) { - lua::pushinteger(L, string[i]); + lua::pushinteger(L, string[i] & 0xFF); lua::rawseti(L, i+1); } } else { @@ -39,8 +39,24 @@ static int l_decode(lua::State* L) { return 1; } +static int l_length(lua::State* L) { + auto string = lua::require_string(L, 1); + return lua::pushinteger(L, util::length_utf8(string)); +} + +static int l_codepoint(lua::State* L) { + std::string_view string = lua::require_string(L, 1); + if (string.empty()) { + return lua::pushinteger(L, 0); + } + uint size; + return lua::pushinteger(L, util::decode_utf8(size, string.data())); +} + const luaL_Reg utf8lib[] = { {"encode", lua::wrap}, {"decode", lua::wrap}, + {"length", lua::wrap}, + {"codepoint", lua::wrap}, {NULL, NULL} }; From ce7698e9ee22b4c149699766ad7ff1411d568f88 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 26 Oct 2024 10:54:33 +0300 Subject: [PATCH 12/14] rename utf8.encode to utf8.tobytes, utf8.decode to utf8.tostring --- src/logic/scripting/lua/libs/libutf8.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/logic/scripting/lua/libs/libutf8.cpp b/src/logic/scripting/lua/libs/libutf8.cpp index 80af5d5d..f273284c 100644 --- a/src/logic/scripting/lua/libs/libutf8.cpp +++ b/src/logic/scripting/lua/libs/libutf8.cpp @@ -54,8 +54,8 @@ static int l_codepoint(lua::State* L) { } const luaL_Reg utf8lib[] = { - {"encode", lua::wrap}, - {"decode", lua::wrap}, + {"tobytes", lua::wrap}, + {"tostring", lua::wrap}, {"length", lua::wrap}, {"codepoint", lua::wrap}, {NULL, NULL} From bd60d05c3ae631df8fa56129b31aae2242b167ab Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 26 Oct 2024 11:07:48 +0300 Subject: [PATCH 13/14] add utf8 library docs --- doc/en/scripting.md | 1 + doc/en/scripting/builtins/libutf8.md | 18 ++++++++++++++++++ doc/ru/scripting.md | 1 + doc/ru/scripting/builtins/libutf8.md | 18 ++++++++++++++++++ 4 files changed, 38 insertions(+) create mode 100644 doc/en/scripting/builtins/libutf8.md create mode 100644 doc/ru/scripting/builtins/libutf8.md diff --git a/doc/en/scripting.md b/doc/en/scripting.md index 2ed46bdb..d1fdc645 100644 --- a/doc/en/scripting.md +++ b/doc/en/scripting.md @@ -21,6 +21,7 @@ Subsections: - [player](scripting/builtins/libplayer.md) - [quat](scripting/builtins/libquat.md) - [time](scripting/builtins/libtime.md) + - [utf8](scripting/builtins/libutf8.md) - [vec2, vec3, vec4](scripting/builtins/libvecn.md) - [world](scripting/builtins/libworld.md) - [Module core:bit_converter](scripting/modules/core_bit_converter.md) diff --git a/doc/en/scripting/builtins/libutf8.md b/doc/en/scripting/builtins/libutf8.md new file mode 100644 index 00000000..55851f88 --- /dev/null +++ b/doc/en/scripting/builtins/libutf8.md @@ -0,0 +1,18 @@ +# *utf8* library + +The library provides functions for working with UTF-8. + +```lua +-- Converts a UTF-8 string to a Bytearray or an array of numbers if +-- the second argument is true +utf8.tobytes(text: str, [optional] usetable=false) -> Bytearray|table + +-- Converts a Bytearray or an array of numbers to a UTF-8 string +utf8.tostring(bytes: Bytearray|table) -> str + +-- Returns the length of a Unicode string +utf8.length(text: str) -> int + +-- Returns the code of the first character of the string +utf8.codepoint(chars: str) -> int +``` diff --git a/doc/ru/scripting.md b/doc/ru/scripting.md index 1f582d46..0900788e 100644 --- a/doc/ru/scripting.md +++ b/doc/ru/scripting.md @@ -21,6 +21,7 @@ - [player](scripting/builtins/libplayer.md) - [quat](scripting/builtins/libquat.md) - [time](scripting/builtins/libtime.md) + - [utf8](scripting/builtins/libutf8.md) - [vec2, vec3, vec4](scripting/builtins/libvecn.md) - [world](scripting/builtins/libworld.md) - [Модуль core:bit_converter](scripting/modules/core_bit_converter.md) diff --git a/doc/ru/scripting/builtins/libutf8.md b/doc/ru/scripting/builtins/libutf8.md new file mode 100644 index 00000000..41805b38 --- /dev/null +++ b/doc/ru/scripting/builtins/libutf8.md @@ -0,0 +1,18 @@ +# Библиотека *utf8* + +Библиотека предоставляет функции для работы с UTF-8. + +```lua +-- Конвертирует UTF-8 строку в Bytearray или массив чисел если +-- второй аргумент - true +utf8.tobytes(text: str, [опционально] usetable=false) -> Bytearray|table + +-- Конвертирует Bytearray или массив чисел в UTF-8 строку +utf8.tostring(bytes: Bytearray|table) -> str + +-- Возвращает длину юникод-строки +utf8.length(text: str) -> int + +-- Возвращает код первого символа строки +utf8.codepoint(chars: str) -> int +``` From 137e6fc7678d67ae7e64c0d4b00140063191bf3f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 26 Oct 2024 11:24:58 +0300 Subject: [PATCH 14/14] add utf8.sub --- doc/en/scripting/builtins/libutf8.md | 3 +++ doc/ru/scripting/builtins/libutf8.md | 3 +++ src/logic/scripting/lua/libs/libutf8.cpp | 11 +++++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/en/scripting/builtins/libutf8.md b/doc/en/scripting/builtins/libutf8.md index 55851f88..e7801f97 100644 --- a/doc/en/scripting/builtins/libutf8.md +++ b/doc/en/scripting/builtins/libutf8.md @@ -15,4 +15,7 @@ utf8.length(text: str) -> int -- Returns the code of the first character of the string utf8.codepoint(chars: str) -> int + +-- Returns a substring from position startchar to endchar inclusive +utf8.sub(text: str, startchar: int, [optional] endchar: int) -> str ``` diff --git a/doc/ru/scripting/builtins/libutf8.md b/doc/ru/scripting/builtins/libutf8.md index 41805b38..b29bb403 100644 --- a/doc/ru/scripting/builtins/libutf8.md +++ b/doc/ru/scripting/builtins/libutf8.md @@ -15,4 +15,7 @@ utf8.length(text: str) -> int -- Возвращает код первого символа строки utf8.codepoint(chars: str) -> int + +-- Возвращает подстроку от позиции startchar до endchar включительно +utf8.sub(text: str, startchar: int, [опционально] endchar: int) -> str ``` diff --git a/src/logic/scripting/lua/libs/libutf8.cpp b/src/logic/scripting/lua/libs/libutf8.cpp index f273284c..182f6295 100644 --- a/src/logic/scripting/lua/libs/libutf8.cpp +++ b/src/logic/scripting/lua/libs/libutf8.cpp @@ -53,10 +53,21 @@ static int l_codepoint(lua::State* L) { return lua::pushinteger(L, util::decode_utf8(size, string.data())); } +static int l_sub(lua::State* L) { + auto string = util::str2u32str_utf8(lua::require_string(L, 1)); + int start = std::max(0, static_cast(lua::tointeger(L, 2) - 1)); + int end = string.length(); + if (lua::gettop(L) >= 3) { + end = std::max(0, static_cast(lua::tointeger(L, 3) - 1)); + } + return lua::pushstring(L, util::u32str2str_utf8(string.substr(start, end))); +} + const luaL_Reg utf8lib[] = { {"tobytes", lua::wrap}, {"tostring", lua::wrap}, {"length", lua::wrap}, {"codepoint", lua::wrap}, + {"sub", lua::wrap}, {NULL, NULL} };