function _map(_pairs, list, func) local new_list = {} for key, value in _pairs(list) do new_list[key] = func(value, key) end return new_list end function map(list, func) return _map(pairs, list, func) end function imap(list, func) return _map(ipairs, list, func) end function _join(_pairs, list) local string = "" for key, value in _pairs(list) do string = string .. value end return string end function join(list) return _join(pairs, list) end function ijoin(list) return _join(ipairs, list) end function render(element) if type(element) == "string" then -- TODO: escape return element end if element[1] then return join(map(element, render)) end local close_tag = "" local self_closing = element.type == "meta" if self_closing then close_tag = "" end return "<"..element.type ..join(map(element.things, function(value, key) if type(key) == "number" then return "" end -- TODO: escape return " "..key.."='"..value.."'" end)) ..">" ..join(imap(element.things, render)) ..close_tag end local function basic_element(name) return function(things) return { type = name, things = things } end end function a(things) if not things.href then print("WARNING: Link `"..ijoin(things).."` doesn't have a href.") end return basic_element("a")(things) end head = basic_element("head") body = basic_element("body") title = basic_element("title") h1 = basic_element("h1") h2 = basic_element("h2") h3 = basic_element("h3") h4 = basic_element("h4") h5 = basic_element("h5") h6 = basic_element("h6") ul = basic_element("ul") ol = basic_element("ol") li = basic_element("li") p = basic_element("p") meta = basic_element("meta") local link = a{href = "https://nulo.in", "Hola, soy html.lua"} local head_block = head{ meta{charset = "utf-8"}, title{"Hello world"}, } local body_block = body{ link, } print(render{head_block, body_block})