This repository has been archived on 2020-06-22. You can view files and clone it, but cannot push or open issues or pull requests.
formspeclib/core.lua

128 lines
4.0 KiB
Lua

--
-- formspeclib core - Better and easier formspecs for Minetest
--
-- © 2017 by luk3yx
--
-- This is only the core rendering process.
formspeclib = {}
local objects = {}
-- formspeclib.version: The version of formspeclib.
formspeclib.version = 0.1
--
-- formspeclib.render(): Renders a formspeclib object into a formspec.
--
-- Syntax: formspeclib.render(formspeclib_object, safe_mode, no_iterations)
--
-- formspeclib_object: The formspeclib object to render.
-- safe_mode: Optional. If it is enabled, the renderer does safety
-- checks so the server does not crash.
-- no_iterations: Optional, not recommended. Only allows formspeclib
-- objects that produce a direct formspec string.
--
formspeclib.render = function(formspec, safe_mode, no_iterations)
if safe_mode and type(formspec) ~= 'table' then
-- Don't throw an error, just don't render the formspec.
return false
end
local compiled = ''
local i
local width
local height
if type(formspec.width) == 'number' then
width = formspec.width
else
width = 0
end
if type(formspec.height) == 'number' then
height = formspec.height
else
height = 0
end
if type(no_iterations) ~= 'number' and no_iterations then
no_iterations = 1
end
for i = 1, #formspec do
if safe_mode and type(formspec[i]) ~= 'table' then
return false
elseif not formspec[i].type then
-- The formspec is defining the global width/height.
if type(formspec[i].width) == 'number' then
width = obj.width
end
if type(formspec[i].height) == 'number' then
height = obj.height
end
elseif objects[formspec[i].type] then
local a
local o
if safe_mode then
a, o = pcall(objects[formspec[i].type], formspec[i], safe_mode)
if not a then o = false end
else
o = objects[formspec[i].type](formspec[i], safe_mode)
end
if type(o) == 'string' then
compiled = compiled .. o
elseif type(o) == 'table' then
if no_iterations and no_iterations < 1 then return false end
local iter
if no_iterations then
iter = no_iterations - 1
elseif safe_mode then
iter = 3
end
o = formspeclib.render(o, safe_mode, iter)
if not o then return false end
compiled = compiled .. o
else
return false
end
else
-- On unknown element
return false
end
end
if width > 0 and height > 0 then
if default and default.gui_bg and default.gui_bg_img and default.gui_slots then
compiled = default.gui_bg .. default.gui_bg_img .. default.gui_slots .. compiled
end
compiled = 'size[' ..
tostring(width) .. ',' .. tostring(height) ..
']' .. compiled
end
return compiled
end
--
-- formspeclib.register_object(): Create a formspeclib object
--
-- Syntax: formspeclib.register_object(name, function)
--
-- name: The name of the object (set in 'type'). It is recommended to make this
-- 'mod:object' unless you are overriding an object.
-- func: The function to generate the object. This function gets sent the
-- formspec chunk to generate, and will return a string or formspeclib
-- formspec, otherwise false to indicate an error.
--
formspeclib.register_object = function(name, func)
if type(func) ~= 'function' then
return false
end
objects[name] = func
return true
end
--
-- formspeclib.escape(): Escape and stringify text.
--
-- This may seem useless, but it is actually quite useful.
--
formspeclib.escape = function(text)
return minetest.formspec_escape(tostring(text))
end