mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-10-31 21:33:02 +00:00
Fixed CLRF Issues (I hope)
This commit is contained in:
parent
29bac504b0
commit
269a73be48
11 changed files with 551 additions and 549 deletions
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
|
@ -1,78 +1,78 @@
|
|||
local Vector3 = require("worldeditadditions_core.utils.vector3")
|
||||
|
||||
local facing_dirs = dofile("./.tests/parse/axes/include_facing_dirs.lua")
|
||||
|
||||
local parse = require("worldeditadditions_core.utils.parse.axes_parser")
|
||||
local parse_keyword = parse.keyword
|
||||
|
||||
|
||||
describe("parse_keyword", function()
|
||||
|
||||
-- Basic tests
|
||||
it("should work on single axes", function()
|
||||
local ktype, axis, sign = parse_keyword("x")
|
||||
assert.are.equals("axis", ktype)
|
||||
assert.are.same({"x"}, axis)
|
||||
assert.are.equals(1, sign)
|
||||
end)
|
||||
|
||||
it("should work with axis clumping", function()
|
||||
local ktype, axis, sign = parse_keyword("zx")
|
||||
assert.are.equals("axis", ktype)
|
||||
assert.are.same({"x", "z"}, axis)
|
||||
assert.are.equals(1, sign)
|
||||
end)
|
||||
|
||||
it("should work with h and v", function()
|
||||
local ktype, axis, sign = parse_keyword("hv")
|
||||
assert.are.equals("axis", ktype)
|
||||
assert.are.same(
|
||||
{"x", "y", "z", rev={"x", "y", "z"}},
|
||||
axis)
|
||||
assert.are.equals(1, sign)
|
||||
end)
|
||||
|
||||
it("should work with h and v in clumping", function()
|
||||
local ktype, axis, sign = parse_keyword("hyxz")
|
||||
assert.are.equals("axis", ktype)
|
||||
assert.are.same(
|
||||
{"x", "y", "z", rev={"x", "z"}},
|
||||
axis)
|
||||
assert.are.equals(1, sign)
|
||||
end)
|
||||
|
||||
it("should work with negatives", function()
|
||||
local ktype, axis, sign = parse_keyword("-xv")
|
||||
assert.are.equals("axis", ktype)
|
||||
assert.are.same({"x", "y", rev={"y"}}, axis)
|
||||
assert.are.equals(-1, sign)
|
||||
end)
|
||||
|
||||
it("should work with dirs", function()
|
||||
local ktype, axis, sign = parse_keyword("left")
|
||||
assert.are.equals("dir", ktype)
|
||||
assert.are.equals("left", axis)
|
||||
assert.are.equals(1, sign)
|
||||
end)
|
||||
|
||||
it("should work with negative dirs", function()
|
||||
local ktype, axis, sign = parse_keyword("-right")
|
||||
assert.are.equals("dir", ktype)
|
||||
assert.are.equals("right", axis)
|
||||
assert.are.equals(-1, sign)
|
||||
end)
|
||||
|
||||
it("should work with mirroring", function()
|
||||
local ktype, axis, sign = parse_keyword("m")
|
||||
assert.are.equals("rev", ktype)
|
||||
assert.are.equals("mirroring", axis)
|
||||
assert.are.equals(nil, sign)
|
||||
end)
|
||||
|
||||
-- Error tests
|
||||
it("should return error for bad axis", function()
|
||||
local ktype, axis, sign = parse_keyword("-axv")
|
||||
assert.are.equals("err", ktype)
|
||||
end)
|
||||
|
||||
end)
|
||||
local Vector3 = require("worldeditadditions_core.utils.vector3")
|
||||
|
||||
local facing_dirs = dofile("./.tests/parse/axes/include_facing_dirs.lua")
|
||||
|
||||
local parse = require("worldeditadditions_core.utils.parse.axes_parser")
|
||||
local parse_keyword = parse.keyword
|
||||
|
||||
|
||||
describe("parse_keyword", function()
|
||||
|
||||
-- Basic tests
|
||||
it("should work on single axes", function()
|
||||
local ktype, axis, sign = parse_keyword("x")
|
||||
assert.are.equals("axis", ktype)
|
||||
assert.are.same({"x"}, axis)
|
||||
assert.are.equals(1, sign)
|
||||
end)
|
||||
|
||||
it("should work with axis clumping", function()
|
||||
local ktype, axis, sign = parse_keyword("zx")
|
||||
assert.are.equals("axis", ktype)
|
||||
assert.are.same({"x", "z"}, axis)
|
||||
assert.are.equals(1, sign)
|
||||
end)
|
||||
|
||||
it("should work with h and v", function()
|
||||
local ktype, axis, sign = parse_keyword("hv")
|
||||
assert.are.equals("axis", ktype)
|
||||
assert.are.same(
|
||||
{"x", "y", "z", rev={"x", "y", "z"}},
|
||||
axis)
|
||||
assert.are.equals(1, sign)
|
||||
end)
|
||||
|
||||
it("should work with h and v in clumping", function()
|
||||
local ktype, axis, sign = parse_keyword("hyxz")
|
||||
assert.are.equals("axis", ktype)
|
||||
assert.are.same(
|
||||
{"x", "y", "z", rev={"x", "z"}},
|
||||
axis)
|
||||
assert.are.equals(1, sign)
|
||||
end)
|
||||
|
||||
it("should work with negatives", function()
|
||||
local ktype, axis, sign = parse_keyword("-xv")
|
||||
assert.are.equals("axis", ktype)
|
||||
assert.are.same({"x", "y", rev={"y"}}, axis)
|
||||
assert.are.equals(-1, sign)
|
||||
end)
|
||||
|
||||
it("should work with dirs", function()
|
||||
local ktype, axis, sign = parse_keyword("left")
|
||||
assert.are.equals("dir", ktype)
|
||||
assert.are.equals("left", axis)
|
||||
assert.are.equals(1, sign)
|
||||
end)
|
||||
|
||||
it("should work with negative dirs", function()
|
||||
local ktype, axis, sign = parse_keyword("-right")
|
||||
assert.are.equals("dir", ktype)
|
||||
assert.are.equals("right", axis)
|
||||
assert.are.equals(-1, sign)
|
||||
end)
|
||||
|
||||
it("should work with mirroring", function()
|
||||
local ktype, axis, sign = parse_keyword("m")
|
||||
assert.are.equals("rev", ktype)
|
||||
assert.are.equals("mirroring", axis)
|
||||
assert.are.equals(nil, sign)
|
||||
end)
|
||||
|
||||
-- Error tests
|
||||
it("should return error for bad axis", function()
|
||||
local ktype, axis, sign = parse_keyword("-axv")
|
||||
assert.are.equals("err", ktype)
|
||||
end)
|
||||
|
||||
end)
|
||||
|
|
|
@ -1,46 +1,46 @@
|
|||
-- ███████ ███████ ██ ███████ ██████ ████████ ██████ ██████ ███████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ███████ █████ ██ █████ ██ ██ ██ ██ ██████ ███████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ███████ ███████ ███████ ███████ ██████ ██ ██████ ██ ██ ███████
|
||||
|
||||
-- Chat commands that operate on selections.
|
||||
|
||||
local wea_cmdpath = worldeditadditions_commands.modpath .. "/commands/selectors/"
|
||||
local weac = worldeditadditions_core
|
||||
|
||||
dofile(wea_cmdpath.."scentre.lua")
|
||||
dofile(wea_cmdpath.."scloud.lua")
|
||||
dofile(wea_cmdpath.."sgrow.lua")
|
||||
dofile(wea_cmdpath.."smake.lua")
|
||||
dofile(wea_cmdpath.."spop.lua")
|
||||
dofile(wea_cmdpath.."spush.lua")
|
||||
dofile(wea_cmdpath.."srel.lua")
|
||||
dofile(wea_cmdpath.."sshift.lua")
|
||||
dofile(wea_cmdpath.."sshrink.lua")
|
||||
dofile(wea_cmdpath.."sstack.lua")
|
||||
|
||||
--- DEPRECATED ---
|
||||
dofile(wea_cmdpath.."scol.lua")
|
||||
dofile(wea_cmdpath.."scube.lua")
|
||||
dofile(wea_cmdpath.."srect.lua")
|
||||
dofile(wea_cmdpath.."sfactor.lua")
|
||||
--- END DEPRECATED ---
|
||||
|
||||
dofile(wea_cmdpath.."unmark.lua")
|
||||
dofile(wea_cmdpath.."mark.lua")
|
||||
dofile(wea_cmdpath.."pos1-2.lua")
|
||||
dofile(wea_cmdpath.."reset.lua")
|
||||
|
||||
-- Aliases
|
||||
weac.register_alias("sfac", "sfactor")
|
||||
|
||||
weac.register_alias("expand", "sgrow", true) -- true = override target
|
||||
weac.register_alias("outset", "sgrow", true) -- true = override target
|
||||
weac.register_alias("contract", "sshrink", true) -- true = override target
|
||||
weac.register_alias("inset", "sshrink", true) -- true = override target
|
||||
|
||||
weac.register_alias("shift", "sshift", true) -- true = override target
|
||||
|
||||
weac.register_alias("1", "pos1", true) -- true = override target
|
||||
weac.register_alias("2", "pos2", true) -- true = override target
|
||||
-- ███████ ███████ ██ ███████ ██████ ████████ ██████ ██████ ███████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ███████ █████ ██ █████ ██ ██ ██ ██ ██████ ███████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ███████ ███████ ███████ ███████ ██████ ██ ██████ ██ ██ ███████
|
||||
|
||||
-- Chat commands that operate on selections.
|
||||
|
||||
local wea_cmdpath = worldeditadditions_commands.modpath .. "/commands/selectors/"
|
||||
local weac = worldeditadditions_core
|
||||
|
||||
dofile(wea_cmdpath.."scentre.lua")
|
||||
dofile(wea_cmdpath.."scloud.lua")
|
||||
dofile(wea_cmdpath.."sgrow.lua")
|
||||
dofile(wea_cmdpath.."smake.lua")
|
||||
dofile(wea_cmdpath.."spop.lua")
|
||||
dofile(wea_cmdpath.."spush.lua")
|
||||
dofile(wea_cmdpath.."srel.lua")
|
||||
dofile(wea_cmdpath.."sshift.lua")
|
||||
dofile(wea_cmdpath.."sshrink.lua")
|
||||
dofile(wea_cmdpath.."sstack.lua")
|
||||
|
||||
--- DEPRECATED ---
|
||||
dofile(wea_cmdpath.."scol.lua")
|
||||
dofile(wea_cmdpath.."scube.lua")
|
||||
dofile(wea_cmdpath.."srect.lua")
|
||||
dofile(wea_cmdpath.."sfactor.lua")
|
||||
--- END DEPRECATED ---
|
||||
|
||||
dofile(wea_cmdpath.."unmark.lua")
|
||||
dofile(wea_cmdpath.."mark.lua")
|
||||
dofile(wea_cmdpath.."pos1-2.lua")
|
||||
dofile(wea_cmdpath.."reset.lua")
|
||||
|
||||
-- Aliases
|
||||
weac.register_alias("sfac", "sfactor")
|
||||
|
||||
weac.register_alias("expand", "sgrow", true) -- true = override target
|
||||
weac.register_alias("outset", "sgrow", true) -- true = override target
|
||||
weac.register_alias("contract", "sshrink", true) -- true = override target
|
||||
weac.register_alias("inset", "sshrink", true) -- true = override target
|
||||
|
||||
weac.register_alias("shift", "sshift", true) -- true = override target
|
||||
|
||||
weac.register_alias("1", "pos1", true) -- true = override target
|
||||
weac.register_alias("2", "pos2", true) -- true = override target
|
||||
|
|
|
@ -1,33 +1,33 @@
|
|||
local wea_c = worldeditadditions_core
|
||||
local Vector3 = wea_c.Vector3
|
||||
|
||||
-- ███████ ██████ ███████ ███ ██ ████████ ███████ ██████
|
||||
-- ██ ██ ██ ████ ██ ██ ██ ██ ██
|
||||
-- ███████ ██ █████ ██ ██ ██ ██ █████ ██████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ███████ ██████ ███████ ██ ████ ██ ███████ ██ ██
|
||||
worldeditadditions_core.register_command("scentre", {
|
||||
params = "",
|
||||
description = "Set WorldEdit region positions 1 and 2 to the centre of the current selection.",
|
||||
privs = {worldedit=true},
|
||||
require_pos = 2,
|
||||
parse = function(params_text)
|
||||
return true
|
||||
end,
|
||||
func = function(name)
|
||||
local mean = Vector3.mean(
|
||||
Vector3.clone(wea_c.pos.get(name, 1)),
|
||||
Vector3.clone(wea_c.pos.get(name, 2))
|
||||
)
|
||||
local pos1, pos2 = Vector3.clone(mean), Vector3.clone(mean)
|
||||
|
||||
pos1 = pos1:floor()
|
||||
pos2 = pos2:ceil()
|
||||
|
||||
wea_c.pos.set_all(name, {pos1, pos2})
|
||||
|
||||
return true, "Position 1 to "..pos1..", Position 2 to "..pos2
|
||||
end,
|
||||
})
|
||||
|
||||
-- lua print(vecs.mean.x..", "..vecs.mean.y..", "..vecs.mean.z)
|
||||
local wea_c = worldeditadditions_core
|
||||
local Vector3 = wea_c.Vector3
|
||||
|
||||
-- ███████ ██████ ███████ ███ ██ ████████ ███████ ██████
|
||||
-- ██ ██ ██ ████ ██ ██ ██ ██ ██
|
||||
-- ███████ ██ █████ ██ ██ ██ ██ █████ ██████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ███████ ██████ ███████ ██ ████ ██ ███████ ██ ██
|
||||
worldeditadditions_core.register_command("scentre", {
|
||||
params = "",
|
||||
description = "Set WorldEdit region positions 1 and 2 to the centre of the current selection.",
|
||||
privs = {worldedit=true},
|
||||
require_pos = 2,
|
||||
parse = function(params_text)
|
||||
return true
|
||||
end,
|
||||
func = function(name)
|
||||
local mean = Vector3.mean(
|
||||
Vector3.clone(wea_c.pos.get(name, 1)),
|
||||
Vector3.clone(wea_c.pos.get(name, 2))
|
||||
)
|
||||
local pos1, pos2 = Vector3.clone(mean), Vector3.clone(mean)
|
||||
|
||||
pos1 = pos1:floor()
|
||||
pos2 = pos2:ceil()
|
||||
|
||||
wea_c.pos.set_all(name, {pos1, pos2})
|
||||
|
||||
return true, "Position 1 to "..pos1..", Position 2 to "..pos2
|
||||
end,
|
||||
})
|
||||
|
||||
-- lua print(vecs.mean.x..", "..vecs.mean.y..", "..vecs.mean.z)
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
local wea = worldeditadditions
|
||||
local wea_c = worldeditadditions_core
|
||||
local Vector3 = wea_c.Vector3
|
||||
|
||||
|
||||
-- ███████ ███████ █████ ██████ ████████ ██████ ██████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ███████ █████ ███████ ██ ██ ██ ██ ██████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ███████ ██ ██ ██ ██████ ██ ██████ ██ ██
|
||||
worldeditadditions_core.register_command("sfactor", {
|
||||
params = "None",
|
||||
description = "DEPRECATED: please use //grow or //shrink instead.",
|
||||
|
||||
privs = { worldedit = true },
|
||||
parse = function(params_text)
|
||||
return params_text
|
||||
end,
|
||||
func = function(name, paramtext)
|
||||
return false, "DEPRECATED: please use //grow or //shrink instead..."
|
||||
end
|
||||
})
|
||||
local wea = worldeditadditions
|
||||
local wea_c = worldeditadditions_core
|
||||
local Vector3 = wea_c.Vector3
|
||||
|
||||
|
||||
-- ███████ ███████ █████ ██████ ████████ ██████ ██████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ███████ █████ ███████ ██ ██ ██ ██ ██████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ███████ ██ ██ ██ ██████ ██ ██████ ██ ██
|
||||
worldeditadditions_core.register_command("sfactor", {
|
||||
params = "None",
|
||||
description = "DEPRECATED: please use //grow or //shrink instead.",
|
||||
|
||||
privs = { worldedit = true },
|
||||
parse = function(params_text)
|
||||
return params_text
|
||||
end,
|
||||
func = function(name, paramtext)
|
||||
return false, "DEPRECATED: please use //grow or //shrink instead..."
|
||||
end
|
||||
})
|
||||
|
|
|
@ -1,42 +1,42 @@
|
|||
-- local wea = worldeditadditions
|
||||
local wea_c = worldeditadditions_core
|
||||
local Vector3 = wea_c.Vector3
|
||||
|
||||
|
||||
-- ███████ ██████ ██████ ██████ ██ ██
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ███████ ██ ███ ██████ ██ ██ ██ █ ██
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ███ ██
|
||||
-- ███████ ██████ ██ ██ ██████ ███ ███
|
||||
|
||||
|
||||
worldeditadditions_core.register_command("sgrow", {
|
||||
params = "<unified axis syntax>",
|
||||
description = "Grow selection region",
|
||||
privs = { worldedit = true },
|
||||
require_pos = 0,
|
||||
parse = function(params_text)
|
||||
local ret = wea_c.split(params_text)
|
||||
if #ret < 1 then return false, "SGROW: No params found!"
|
||||
else return true, ret end
|
||||
end,
|
||||
func = function(name, params_text)
|
||||
local facing = wea_c.player_dir(name)
|
||||
local min, max = wea_c.parse.directions(params_text, facing)
|
||||
if not min then return false, max end
|
||||
|
||||
local pos1 = wea_c.pos.get(name, 1)
|
||||
local pos2 = wea_c.pos.get(name, 2)
|
||||
|
||||
if not pos2 then wea_c.pos.set(name, 2, pos1)
|
||||
else pos1, pos2 = Vector3.sort(pos1, pos2) end
|
||||
|
||||
pos1, pos2 = pos1:add(min), pos2:add(max)
|
||||
|
||||
wea_c.pos.set_all(name, {pos1, pos2})
|
||||
return true, "Position 1 to "..pos1..", Position 2 to "..pos2
|
||||
end,
|
||||
})
|
||||
|
||||
-- Tests
|
||||
-- //srel front 5 left 3 y 2
|
||||
-- local wea = worldeditadditions
|
||||
local wea_c = worldeditadditions_core
|
||||
local Vector3 = wea_c.Vector3
|
||||
|
||||
|
||||
-- ███████ ██████ ██████ ██████ ██ ██
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ███████ ██ ███ ██████ ██ ██ ██ █ ██
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ███ ██
|
||||
-- ███████ ██████ ██ ██ ██████ ███ ███
|
||||
|
||||
|
||||
worldeditadditions_core.register_command("sgrow", {
|
||||
params = "<unified axis syntax>",
|
||||
description = "Grow selection region",
|
||||
privs = { worldedit = true },
|
||||
require_pos = 0,
|
||||
parse = function(params_text)
|
||||
local ret = wea_c.split(params_text)
|
||||
if #ret < 1 then return false, "SGROW: No params found!"
|
||||
else return true, ret end
|
||||
end,
|
||||
func = function(name, params_text)
|
||||
local facing = wea_c.player_dir(name)
|
||||
local min, max = wea_c.parse.directions(params_text, facing)
|
||||
if not min then return false, max end
|
||||
|
||||
local pos1 = wea_c.pos.get(name, 1)
|
||||
local pos2 = wea_c.pos.get(name, 2)
|
||||
|
||||
if not pos2 then wea_c.pos.set(name, 2, pos1)
|
||||
else pos1, pos2 = Vector3.sort(pos1, pos2) end
|
||||
|
||||
pos1, pos2 = pos1:add(min), pos2:add(max)
|
||||
|
||||
wea_c.pos.set_all(name, {pos1, pos2})
|
||||
return true, "Position 1 to "..pos1..", Position 2 to "..pos2
|
||||
end,
|
||||
})
|
||||
|
||||
-- Tests
|
||||
-- //srel front 5 left 3 y 2
|
||||
|
|
|
@ -1,131 +1,131 @@
|
|||
local wea_c = worldeditadditions_core
|
||||
local Vector3 = wea_c.Vector3
|
||||
|
||||
|
||||
-- ███████ ███ ███ █████ ██ ██ ███████
|
||||
-- ██ ████ ████ ██ ██ ██ ██ ██
|
||||
-- ███████ ██ ████ ██ ███████ █████ █████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ███████ ██ ██ ██ ██ ██ ██ ███████
|
||||
worldeditadditions_core.register_command("smake", {
|
||||
params = "<operation:odd|even|equal> <mode:grow|shrink|average> [<target=xyz> [<base>]]",
|
||||
description = "Make one or more axes of the current selection odd, even, or equal to another.",
|
||||
privs = { worldedit = true },
|
||||
require_pos = 2,
|
||||
parse = function(params_text)
|
||||
-- Split params_text, check for missing arguments and fill in empty spots
|
||||
local parts = wea_c.split(params_text, "%s+", false)
|
||||
if #parts < 2 then
|
||||
return false, "Error: Not enough arguments. Expected \"<operation> <mode> [<target=xyz> [<base>]]\"."
|
||||
else
|
||||
for i=3,4 do if not parts[i] then parts[i] = false end end
|
||||
end
|
||||
|
||||
-- Initialize local variables and sets
|
||||
local oper, mode, targ, base = wea_c.table.unpack(parts)
|
||||
local operSet, modeSet = wea_c.table.makeset {"equal", "odd", "even"}, wea_c.table.makeset {"grow", "shrink", "avg"}
|
||||
|
||||
-- Main Logic
|
||||
-- Check base if base is present and if so valid.
|
||||
if base then
|
||||
if base:match("[xyz]") then -- ensure correct base syntax
|
||||
base = base:match("[xyz]")
|
||||
else
|
||||
return false, "Error: Invalid base \""..base.."\". Expected \"x\", \"y\" or \"z\"."
|
||||
end
|
||||
end
|
||||
|
||||
-- Resolve target then mode (in that order incase mode is target).
|
||||
if not targ then -- If no target set to default (xz)
|
||||
targ = "xz"
|
||||
elseif targ:match("[xyz]+") then -- ensure correct target syntax
|
||||
targ = table.concat(wea_c.tochars(targ:match("[xyz]+"),true,true))
|
||||
else
|
||||
return false, "Error: Invalid <target> \""..targ.."\". Expected \"x\" and or \"y\" and or \"z\"."
|
||||
end
|
||||
|
||||
if mode == "average" then -- If mode is average set to avg
|
||||
mode = "avg"
|
||||
elseif mode:match("[xyz]+") then -- If target is actually base set vars to correct values.
|
||||
base, targ, mode = targ:sub(1,1), table.concat(wea_c.tochars(mode:match("[xyz]+"),true,true)), false
|
||||
elseif not modeSet[mode] and not base then -- If mode is invalid and base isn't present throw error
|
||||
return false, "Error: Invalid <mode> \""..mode.."\". Expected \"grow\", \"shrink\", or \"average\"/\"avg\"."
|
||||
end
|
||||
|
||||
if base then
|
||||
if oper ~= "equal" then base = false -- If operation isn't equalize we don't need <base>
|
||||
elseif targ:match(base) then -- Else check that base is not in target and return error if it is
|
||||
return false, "Error: <base> ("..base..") cannot be included in <target> ("..targ..")."
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if operator is valid
|
||||
if not operSet[oper] then
|
||||
return false, "Error: Invalid operator \""..oper.."\". Expected \"odd\", \"even\" or \"equal\"."
|
||||
end
|
||||
|
||||
return true, oper, mode, targ, base
|
||||
end,
|
||||
func = function(name, oper, mode, targ, base)
|
||||
local pos1, pos2 = Vector3.clone(wea_c.pos.get(name, 1)), Vector3.clone(wea_c.pos.get(name, 2))
|
||||
local eval -- Declare eval placeholder function to edit later
|
||||
|
||||
local delta = pos2 - pos1 -- local delta equation: Vd(a) = V2(a) - V1(a)
|
||||
local _tl = #targ -- Get targ length as a variable incase mode is "average"/"avg"
|
||||
local targ = wea_c.tocharset(targ) -- Break up targ string into set table
|
||||
local _m = 0 -- _m is the container to hold the max, min or average (depending on the mode) of the axes in targ
|
||||
|
||||
-- set _m to the max, min or mean of the target axes depending on mode or base if it exists
|
||||
if base then _m = delta[base]
|
||||
elseif mode == "avg" then
|
||||
for k,v in pairs(targ) do _m = _m + math.abs(delta[k]) end
|
||||
_m = _m / _tl
|
||||
elseif mode == "grow" then
|
||||
for k,v in pairs(targ) do if math.abs(delta[k]) > _m then _m = math.abs(delta[k]) end end
|
||||
else
|
||||
-- Take output of next(targ), put it in a table, wrap the table in brackets to force evlauation so that
|
||||
-- we can call the first element of that table to serve as the key for a call to delta.
|
||||
_m = delta[({next(targ)})[1]]
|
||||
for k,v in pairs(targ) do if math.abs(delta[k]) < _m then _m = math.abs(delta[k]) end end
|
||||
end
|
||||
|
||||
if oper == "even" then
|
||||
eval = function(int)
|
||||
local tmp, abs, neg = int / 2, math.abs(int), int < 0
|
||||
if math.floor(tmp) ~= tmp then
|
||||
if mode == "avg" then
|
||||
if int > _m then int = abs - 1
|
||||
else int = abs + 1 end
|
||||
elseif mode == "shrink" and abs > 0 then int = abs - 1
|
||||
else int = abs + 1 end
|
||||
end
|
||||
if neg then int = int * -1 end -- Ensure correct facing direction
|
||||
return int
|
||||
end
|
||||
elseif oper == "odd" then
|
||||
eval = function(int)
|
||||
local tmp, abs, neg = int / 2, math.abs(int), int < 0
|
||||
if math.floor(tmp) == tmp then
|
||||
if mode == "avg" then
|
||||
if int > _m then int = abs - 1
|
||||
else int = abs + 1 end
|
||||
elseif mode == "shrink" and abs > 0 then int = abs - 1
|
||||
else int = abs + 1 end
|
||||
end
|
||||
if neg then int = int * -1 end
|
||||
return int
|
||||
end
|
||||
else -- Case: oper == "equal"
|
||||
eval = function(int)
|
||||
-- Bug: shrink sets pos2 to pos1
|
||||
if int < 0 then return _m * -1
|
||||
else return _m end
|
||||
end
|
||||
end
|
||||
|
||||
for k,_ in pairs(targ) do delta[k] = eval(delta[k]) end
|
||||
|
||||
wea_c.pos.set(name, 2, pos1 + delta)
|
||||
return true, "Position 2 to "..pos2
|
||||
end
|
||||
})
|
||||
local wea_c = worldeditadditions_core
|
||||
local Vector3 = wea_c.Vector3
|
||||
|
||||
|
||||
-- ███████ ███ ███ █████ ██ ██ ███████
|
||||
-- ██ ████ ████ ██ ██ ██ ██ ██
|
||||
-- ███████ ██ ████ ██ ███████ █████ █████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ███████ ██ ██ ██ ██ ██ ██ ███████
|
||||
worldeditadditions_core.register_command("smake", {
|
||||
params = "<operation:odd|even|equal> <mode:grow|shrink|average> [<target=xyz> [<base>]]",
|
||||
description = "Make one or more axes of the current selection odd, even, or equal to another.",
|
||||
privs = { worldedit = true },
|
||||
require_pos = 2,
|
||||
parse = function(params_text)
|
||||
-- Split params_text, check for missing arguments and fill in empty spots
|
||||
local parts = wea_c.split(params_text, "%s+", false)
|
||||
if #parts < 2 then
|
||||
return false, "Error: Not enough arguments. Expected \"<operation> <mode> [<target=xyz> [<base>]]\"."
|
||||
else
|
||||
for i=3,4 do if not parts[i] then parts[i] = false end end
|
||||
end
|
||||
|
||||
-- Initialize local variables and sets
|
||||
local oper, mode, targ, base = wea_c.table.unpack(parts)
|
||||
local operSet, modeSet = wea_c.table.makeset {"equal", "odd", "even"}, wea_c.table.makeset {"grow", "shrink", "avg"}
|
||||
|
||||
-- Main Logic
|
||||
-- Check base if base is present and if so valid.
|
||||
if base then
|
||||
if base:match("[xyz]") then -- ensure correct base syntax
|
||||
base = base:match("[xyz]")
|
||||
else
|
||||
return false, "Error: Invalid base \""..base.."\". Expected \"x\", \"y\" or \"z\"."
|
||||
end
|
||||
end
|
||||
|
||||
-- Resolve target then mode (in that order incase mode is target).
|
||||
if not targ then -- If no target set to default (xz)
|
||||
targ = "xz"
|
||||
elseif targ:match("[xyz]+") then -- ensure correct target syntax
|
||||
targ = table.concat(wea_c.tochars(targ:match("[xyz]+"),true,true))
|
||||
else
|
||||
return false, "Error: Invalid <target> \""..targ.."\". Expected \"x\" and or \"y\" and or \"z\"."
|
||||
end
|
||||
|
||||
if mode == "average" then -- If mode is average set to avg
|
||||
mode = "avg"
|
||||
elseif mode:match("[xyz]+") then -- If target is actually base set vars to correct values.
|
||||
base, targ, mode = targ:sub(1,1), table.concat(wea_c.tochars(mode:match("[xyz]+"),true,true)), false
|
||||
elseif not modeSet[mode] and not base then -- If mode is invalid and base isn't present throw error
|
||||
return false, "Error: Invalid <mode> \""..mode.."\". Expected \"grow\", \"shrink\", or \"average\"/\"avg\"."
|
||||
end
|
||||
|
||||
if base then
|
||||
if oper ~= "equal" then base = false -- If operation isn't equalize we don't need <base>
|
||||
elseif targ:match(base) then -- Else check that base is not in target and return error if it is
|
||||
return false, "Error: <base> ("..base..") cannot be included in <target> ("..targ..")."
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if operator is valid
|
||||
if not operSet[oper] then
|
||||
return false, "Error: Invalid operator \""..oper.."\". Expected \"odd\", \"even\" or \"equal\"."
|
||||
end
|
||||
|
||||
return true, oper, mode, targ, base
|
||||
end,
|
||||
func = function(name, oper, mode, targ, base)
|
||||
local pos1, pos2 = Vector3.clone(wea_c.pos.get(name, 1)), Vector3.clone(wea_c.pos.get(name, 2))
|
||||
local eval -- Declare eval placeholder function to edit later
|
||||
|
||||
local delta = pos2 - pos1 -- local delta equation: Vd(a) = V2(a) - V1(a)
|
||||
local _tl = #targ -- Get targ length as a variable incase mode is "average"/"avg"
|
||||
local targ = wea_c.tocharset(targ) -- Break up targ string into set table
|
||||
local _m = 0 -- _m is the container to hold the max, min or average (depending on the mode) of the axes in targ
|
||||
|
||||
-- set _m to the max, min or mean of the target axes depending on mode or base if it exists
|
||||
if base then _m = delta[base]
|
||||
elseif mode == "avg" then
|
||||
for k,v in pairs(targ) do _m = _m + math.abs(delta[k]) end
|
||||
_m = _m / _tl
|
||||
elseif mode == "grow" then
|
||||
for k,v in pairs(targ) do if math.abs(delta[k]) > _m then _m = math.abs(delta[k]) end end
|
||||
else
|
||||
-- Take output of next(targ), put it in a table, wrap the table in brackets to force evlauation so that
|
||||
-- we can call the first element of that table to serve as the key for a call to delta.
|
||||
_m = delta[({next(targ)})[1]]
|
||||
for k,v in pairs(targ) do if math.abs(delta[k]) < _m then _m = math.abs(delta[k]) end end
|
||||
end
|
||||
|
||||
if oper == "even" then
|
||||
eval = function(int)
|
||||
local tmp, abs, neg = int / 2, math.abs(int), int < 0
|
||||
if math.floor(tmp) ~= tmp then
|
||||
if mode == "avg" then
|
||||
if int > _m then int = abs - 1
|
||||
else int = abs + 1 end
|
||||
elseif mode == "shrink" and abs > 0 then int = abs - 1
|
||||
else int = abs + 1 end
|
||||
end
|
||||
if neg then int = int * -1 end -- Ensure correct facing direction
|
||||
return int
|
||||
end
|
||||
elseif oper == "odd" then
|
||||
eval = function(int)
|
||||
local tmp, abs, neg = int / 2, math.abs(int), int < 0
|
||||
if math.floor(tmp) == tmp then
|
||||
if mode == "avg" then
|
||||
if int > _m then int = abs - 1
|
||||
else int = abs + 1 end
|
||||
elseif mode == "shrink" and abs > 0 then int = abs - 1
|
||||
else int = abs + 1 end
|
||||
end
|
||||
if neg then int = int * -1 end
|
||||
return int
|
||||
end
|
||||
else -- Case: oper == "equal"
|
||||
eval = function(int)
|
||||
-- Bug: shrink sets pos2 to pos1
|
||||
if int < 0 then return _m * -1
|
||||
else return _m end
|
||||
end
|
||||
end
|
||||
|
||||
for k,_ in pairs(targ) do delta[k] = eval(delta[k]) end
|
||||
|
||||
wea_c.pos.set(name, 2, pos1 + delta)
|
||||
return true, "Position 2 to "..pos2
|
||||
end
|
||||
})
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
-- local wea = worldeditadditions
|
||||
local wea_c = worldeditadditions_core
|
||||
local Vector3 = wea_c.Vector3
|
||||
|
||||
|
||||
-- ███████ ██████ ███████ ██
|
||||
-- ██ ██ ██ ██ ██
|
||||
-- ███████ ██████ █████ ██
|
||||
-- ██ ██ ██ ██ ██
|
||||
-- ███████ ██ ██ ███████ ███████
|
||||
|
||||
|
||||
worldeditadditions_core.register_command("srel", {
|
||||
params = "<unified axis syntax>",
|
||||
description = "Set WorldEdit region position 2 relative to position 1 and player facing.",
|
||||
privs = { worldedit = true },
|
||||
require_pos = 0,
|
||||
parse = function(params_text)
|
||||
local ret = wea_c.split(params_text)
|
||||
if #ret < 1 then return false, "SREL: No params found!"
|
||||
else return true, ret end
|
||||
end,
|
||||
func = function(name, params_text)
|
||||
local facing = wea_c.player_dir(name)
|
||||
local vec, err = wea_c.parse.directions(params_text, facing, true)
|
||||
if not vec then return false, err end
|
||||
|
||||
local pos1 = wea_c.pos.get(name, 1)
|
||||
local pos2 = pos1:add(vec)
|
||||
|
||||
wea_c.pos.set_all(name, {pos1, pos2})
|
||||
return true, "Position 1 to "..pos1..", Position 2 to "..pos2
|
||||
end,
|
||||
})
|
||||
|
||||
-- Tests
|
||||
-- //srel front 5 left 3 y 2
|
||||
-- local wea = worldeditadditions
|
||||
local wea_c = worldeditadditions_core
|
||||
local Vector3 = wea_c.Vector3
|
||||
|
||||
|
||||
-- ███████ ██████ ███████ ██
|
||||
-- ██ ██ ██ ██ ██
|
||||
-- ███████ ██████ █████ ██
|
||||
-- ██ ██ ██ ██ ██
|
||||
-- ███████ ██ ██ ███████ ███████
|
||||
|
||||
|
||||
worldeditadditions_core.register_command("srel", {
|
||||
params = "<unified axis syntax>",
|
||||
description = "Set WorldEdit region position 2 relative to position 1 and player facing.",
|
||||
privs = { worldedit = true },
|
||||
require_pos = 0,
|
||||
parse = function(params_text)
|
||||
local ret = wea_c.split(params_text)
|
||||
if #ret < 1 then return false, "SREL: No params found!"
|
||||
else return true, ret end
|
||||
end,
|
||||
func = function(name, params_text)
|
||||
local facing = wea_c.player_dir(name)
|
||||
local vec, err = wea_c.parse.directions(params_text, facing, true)
|
||||
if not vec then return false, err end
|
||||
|
||||
local pos1 = wea_c.pos.get(name, 1)
|
||||
local pos2 = pos1:add(vec)
|
||||
|
||||
wea_c.pos.set_all(name, {pos1, pos2})
|
||||
return true, "Position 1 to "..pos1..", Position 2 to "..pos2
|
||||
end,
|
||||
})
|
||||
|
||||
-- Tests
|
||||
-- //srel front 5 left 3 y 2
|
||||
|
|
|
@ -1,42 +1,42 @@
|
|||
-- local wea = worldeditadditions
|
||||
local wea_c = worldeditadditions_core
|
||||
local Vector3 = wea_c.Vector3
|
||||
|
||||
|
||||
-- ███████ ███████ ██ ██ ██████ ██ ███ ██ ██ ██
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ████ ██ ██ ██
|
||||
-- ███████ ███████ ███████ ██████ ██ ██ ██ ██ █████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ███████ ███████ ██ ██ ██ ██ ██ ██ ████ ██ ██
|
||||
|
||||
|
||||
worldeditadditions_core.register_command("sshrink", {
|
||||
params = "<unified axis syntax>",
|
||||
description = "Shrink selection region",
|
||||
privs = { worldedit = true },
|
||||
require_pos = 0,
|
||||
parse = function(params_text)
|
||||
local ret = wea_c.split(params_text)
|
||||
if #ret < 1 then return false, "Error: No params found!"
|
||||
else return true, ret end
|
||||
end,
|
||||
func = function(name, params_text)
|
||||
local facing = wea_c.player_dir(name)
|
||||
local min, max = wea_c.parse.directions(params_text, facing)
|
||||
if not min then return false, max end
|
||||
|
||||
local pos1 = wea_c.pos.get(name, 1)
|
||||
local pos2 = wea_c.pos.get(name, 2)
|
||||
|
||||
if not pos2 then wea_c.pos.set(name, 2, pos1)
|
||||
else pos1, pos2 = Vector3.sort(pos1, pos2) end
|
||||
|
||||
pos1, pos2 = pos1:add(max), pos2:add(min)
|
||||
|
||||
wea_c.pos.set_all(name, {pos1, pos2})
|
||||
return true, "Position 1 to "..pos1..", Position 2 to "..pos2
|
||||
end,
|
||||
})
|
||||
|
||||
-- Tests
|
||||
-- //srel front 5 left 3 y 2
|
||||
-- local wea = worldeditadditions
|
||||
local wea_c = worldeditadditions_core
|
||||
local Vector3 = wea_c.Vector3
|
||||
|
||||
|
||||
-- ███████ ███████ ██ ██ ██████ ██ ███ ██ ██ ██
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ████ ██ ██ ██
|
||||
-- ███████ ███████ ███████ ██████ ██ ██ ██ ██ █████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ███████ ███████ ██ ██ ██ ██ ██ ██ ████ ██ ██
|
||||
|
||||
|
||||
worldeditadditions_core.register_command("sshrink", {
|
||||
params = "<unified axis syntax>",
|
||||
description = "Shrink selection region",
|
||||
privs = { worldedit = true },
|
||||
require_pos = 0,
|
||||
parse = function(params_text)
|
||||
local ret = wea_c.split(params_text)
|
||||
if #ret < 1 then return false, "Error: No params found!"
|
||||
else return true, ret end
|
||||
end,
|
||||
func = function(name, params_text)
|
||||
local facing = wea_c.player_dir(name)
|
||||
local min, max = wea_c.parse.directions(params_text, facing)
|
||||
if not min then return false, max end
|
||||
|
||||
local pos1 = wea_c.pos.get(name, 1)
|
||||
local pos2 = wea_c.pos.get(name, 2)
|
||||
|
||||
if not pos2 then wea_c.pos.set(name, 2, pos1)
|
||||
else pos1, pos2 = Vector3.sort(pos1, pos2) end
|
||||
|
||||
pos1, pos2 = pos1:add(max), pos2:add(min)
|
||||
|
||||
wea_c.pos.set_all(name, {pos1, pos2})
|
||||
return true, "Position 1 to "..pos1..", Position 2 to "..pos2
|
||||
end,
|
||||
})
|
||||
|
||||
-- Tests
|
||||
-- //srel front 5 left 3 y 2
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
local wea_c = worldeditadditions_core
|
||||
-- local Vector3 = wea_c.Vector3
|
||||
|
||||
-- ██ ██ █████ ███████ ██████ █████ ██████ ███████ ███████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██ ██ ███████ ███████ ██████ ███████ ██████ ███████ █████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██████ ██ ██ ███████ ██ ██ ██ ██ ██ ███████ ███████
|
||||
|
||||
worldeditadditions_core.register_command("uasparse", {
|
||||
params = "<unified axis syntax>",
|
||||
description = "Debug command. Returns min and max vectors for given inputs",
|
||||
privs = { worldedit = true },
|
||||
-- require_pos = 2,
|
||||
parse = function(params_text)
|
||||
local ret = wea_c.split(params_text)
|
||||
if #ret < 1 then return false, "Error: No params found!"
|
||||
else return true, ret end
|
||||
end,
|
||||
func = function(name, params_text)
|
||||
local facing = wea_c.player_dir(name)
|
||||
local min, max = wea_c.parse.directions(params_text, facing)
|
||||
if not min then
|
||||
return false, max
|
||||
else
|
||||
return true, "Min: "..min.." Max: "..max
|
||||
end
|
||||
end
|
||||
})
|
||||
local wea_c = worldeditadditions_core
|
||||
-- local Vector3 = wea_c.Vector3
|
||||
|
||||
-- ██ ██ █████ ███████ ██████ █████ ██████ ███████ ███████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██ ██ ███████ ███████ ██████ ███████ ██████ ███████ █████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██████ ██ ██ ███████ ██ ██ ██ ██ ██ ███████ ███████
|
||||
|
||||
worldeditadditions_core.register_command("uasparse", {
|
||||
params = "<unified axis syntax>",
|
||||
description = "Debug command. Returns min and max vectors for given inputs",
|
||||
privs = { worldedit = true },
|
||||
-- require_pos = 2,
|
||||
parse = function(params_text)
|
||||
local ret = wea_c.split(params_text)
|
||||
if #ret < 1 then return false, "Error: No params found!"
|
||||
else return true, ret end
|
||||
end,
|
||||
func = function(name, params_text)
|
||||
local facing = wea_c.player_dir(name)
|
||||
local min, max = wea_c.parse.directions(params_text, facing)
|
||||
if not min then
|
||||
return false, max
|
||||
else
|
||||
return true, "Min: "..min.." Max: "..max
|
||||
end
|
||||
end
|
||||
})
|
||||
|
|
|
@ -1,90 +1,90 @@
|
|||
-- Licence: GPLv2 (MPL-2.0 is compatible, so we can use this here)
|
||||
-- Source: https://stackoverflow.com/a/43582076/1460422
|
||||
|
||||
-- gsplit: iterate over substrings in a string separated by a pattern
|
||||
--
|
||||
-- Parameters:
|
||||
-- text (string) - the string to iterate over
|
||||
-- pattern (string) - the separator pattern
|
||||
-- plain (boolean) - if true (or truthy), pattern is interpreted as a plain
|
||||
-- string, not a Lua pattern
|
||||
--
|
||||
-- Returns: iterator
|
||||
--
|
||||
-- Usage:
|
||||
-- for substr in gsplit(text, pattern, plain) do
|
||||
-- doSomething(substr)
|
||||
-- end
|
||||
local function gsplit(text, pattern, plain)
|
||||
local splitStart, length = 1, #text
|
||||
return function ()
|
||||
if splitStart then
|
||||
local sepStart, sepEnd = string.find(text, pattern, splitStart, plain)
|
||||
local ret
|
||||
if not sepStart then
|
||||
ret = string.sub(text, splitStart)
|
||||
splitStart = nil
|
||||
elseif sepEnd < sepStart then
|
||||
-- Empty separator!
|
||||
ret = string.sub(text, splitStart, sepStart)
|
||||
if sepStart < length then
|
||||
splitStart = sepStart + 1
|
||||
else
|
||||
splitStart = nil
|
||||
end
|
||||
else
|
||||
ret = sepStart > splitStart and string.sub(text, splitStart, sepStart - 1) or ''
|
||||
splitStart = sepEnd + 1
|
||||
end
|
||||
return ret
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Split a string into substrings separated by a pattern. -- Deprecated
|
||||
-- @param text string The string to iterate over
|
||||
-- @param pattern string The separator pattern
|
||||
-- @param plain boolean If true (or truthy), pattern is interpreted as a
|
||||
-- plain string, not a Lua pattern
|
||||
-- @returns table A sequence table containing the substrings
|
||||
local function dsplit(text, pattern, plain)
|
||||
local ret = {}
|
||||
for match in gsplit(text, pattern, plain) do
|
||||
table.insert(ret, match)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
--- Split a string into substrings separated by a pattern.
|
||||
-- @param str string The string to iterate over
|
||||
-- @param dlm="%s+" string The delimiter (separator) pattern. If a falsey value is passed, then the default value is used.
|
||||
-- @param plain boolean If true (or truthy), pattern is interpreted as a
|
||||
-- plain string, not a Lua pattern
|
||||
-- @returns table A sequence table containing the substrings
|
||||
local function split(str,dlm,plain)
|
||||
if not dlm then dlm = "%s+" end
|
||||
local pos, ret = 0, {}
|
||||
local ins, i = str:find(dlm,pos,plain)
|
||||
-- "if plain" shaves off some time in the while statement
|
||||
if plain then
|
||||
while ins do
|
||||
table.insert(ret,str:sub(pos,ins - 1))
|
||||
pos = ins + #dlm
|
||||
ins = str:find(dlm,pos,true)
|
||||
end
|
||||
else
|
||||
while ins do
|
||||
table.insert(ret,str:sub(pos,ins - 1))
|
||||
pos = i + 1
|
||||
ins, i = str:find(dlm,pos)
|
||||
end
|
||||
end
|
||||
-- print(pos..","..#str)
|
||||
if str:sub(pos,#str) ~= "" then
|
||||
table.insert(ret,str:sub(pos,#str))
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
-- Licence: GPLv2 (MPL-2.0 is compatible, so we can use this here)
|
||||
-- Source: https://stackoverflow.com/a/43582076/1460422
|
||||
|
||||
-- gsplit: iterate over substrings in a string separated by a pattern
|
||||
--
|
||||
-- Parameters:
|
||||
-- text (string) - the string to iterate over
|
||||
-- pattern (string) - the separator pattern
|
||||
-- plain (boolean) - if true (or truthy), pattern is interpreted as a plain
|
||||
-- string, not a Lua pattern
|
||||
--
|
||||
-- Returns: iterator
|
||||
--
|
||||
-- Usage:
|
||||
-- for substr in gsplit(text, pattern, plain) do
|
||||
-- doSomething(substr)
|
||||
-- end
|
||||
local function gsplit(text, pattern, plain)
|
||||
local splitStart, length = 1, #text
|
||||
return function ()
|
||||
if splitStart then
|
||||
local sepStart, sepEnd = string.find(text, pattern, splitStart, plain)
|
||||
local ret
|
||||
if not sepStart then
|
||||
ret = string.sub(text, splitStart)
|
||||
splitStart = nil
|
||||
elseif sepEnd < sepStart then
|
||||
-- Empty separator!
|
||||
ret = string.sub(text, splitStart, sepStart)
|
||||
if sepStart < length then
|
||||
splitStart = sepStart + 1
|
||||
else
|
||||
splitStart = nil
|
||||
end
|
||||
else
|
||||
ret = sepStart > splitStart and string.sub(text, splitStart, sepStart - 1) or ''
|
||||
splitStart = sepEnd + 1
|
||||
end
|
||||
return ret
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Split a string into substrings separated by a pattern. -- Deprecated
|
||||
-- @param text string The string to iterate over
|
||||
-- @param pattern string The separator pattern
|
||||
-- @param plain boolean If true (or truthy), pattern is interpreted as a
|
||||
-- plain string, not a Lua pattern
|
||||
-- @returns table A sequence table containing the substrings
|
||||
local function dsplit(text, pattern, plain)
|
||||
local ret = {}
|
||||
for match in gsplit(text, pattern, plain) do
|
||||
table.insert(ret, match)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
--- Split a string into substrings separated by a pattern.
|
||||
-- @param str string The string to iterate over
|
||||
-- @param dlm="%s+" string The delimiter (separator) pattern. If a falsey value is passed, then the default value is used.
|
||||
-- @param plain boolean If true (or truthy), pattern is interpreted as a
|
||||
-- plain string, not a Lua pattern
|
||||
-- @returns table A sequence table containing the substrings
|
||||
local function split(str,dlm,plain)
|
||||
if not dlm then dlm = "%s+" end
|
||||
local pos, ret = 0, {}
|
||||
local ins, i = str:find(dlm,pos,plain)
|
||||
-- "if plain" shaves off some time in the while statement
|
||||
if plain then
|
||||
while ins do
|
||||
table.insert(ret,str:sub(pos,ins - 1))
|
||||
pos = ins + #dlm
|
||||
ins = str:find(dlm,pos,true)
|
||||
end
|
||||
else
|
||||
while ins do
|
||||
table.insert(ret,str:sub(pos,ins - 1))
|
||||
pos = i + 1
|
||||
ins, i = str:find(dlm,pos)
|
||||
end
|
||||
end
|
||||
-- print(pos..","..#str)
|
||||
if str:sub(pos,#str) ~= "" then
|
||||
table.insert(ret,str:sub(pos,#str))
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
return split
|
Loading…
Reference in a new issue