diff options
author | sanine <sanine.not@pm.me> | 2023-08-18 01:42:20 -0500 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2023-08-18 01:42:20 -0500 |
commit | 83448304527d8a1dde233f2f33b98124bced5f88 (patch) | |
tree | e0992f3083c5fbfbe84c319fd9f0a5fc1a9c64d2 /marigold.lua | |
parent | 9363bfcbd23b4652af40bf56273ade6f395539f4 (diff) |
implement some basic svg rendering
Diffstat (limited to 'marigold.lua')
-rw-r--r-- | marigold.lua | 101 |
1 files changed, 65 insertions, 36 deletions
diff --git a/marigold.lua b/marigold.lua index a6223df..9daa808 100644 --- a/marigold.lua +++ b/marigold.lua @@ -36,27 +36,6 @@ local marigold = {} -marigold.get_metavars = function() - local vars = { - "AUTH_TYPE", "CONTENT_LENGTH", - "CONTENT_TYPE", "GATEWAY_INTERFACE", - "PATH_INFO", "PATH_TRANSLATED", - "QUERY_STRING", "REMOTE_ADDR", - "REMOTE_HOST", "REMOTE_IDENT", - "REMOTE_USER", "REQUEST_METHOD", - "SCRIPT_NAME", "SERVER_NAME", - "SERVER_PORT", "SERVER_PROTOCOL", - "SERVER_SOFTWARE" - } - - local metavars = {} - for _, var in ipairs(vars) do - metavars[string.lower(var)] = os.getenv(var) - end - return metavars -end - - marigold.h = function(tag_type, content, tbl) if type(content) == 'table' and tbl == nil then tbl = content @@ -90,7 +69,7 @@ marigold.h = function(tag_type, content, tbl) end -marigold.html = function(tbl, indent_level) +local function render_internal(tbl, indent_level) indent_level = indent_level or 0 local indent = string.rep('\t', indent_level) @@ -117,7 +96,7 @@ marigold.html = function(tbl, indent_level) local children = '' for _, child in ipairs(tbl.children) do - children = children .. marigold.html(child, indent_level+1) .. '\n' + children = children .. render_internal(child, indent_level+1) .. '\n' end return string.format('%s%s%s\n%s%s%s', @@ -126,25 +105,75 @@ marigold.html = function(tbl, indent_level) indent, close) end -marigold.decode_percent = function(str) - return string.gsub(str, "%%(%x%x)", function(digits) - return string.char(tonumber(digits, 16)) - end) +marigold.render = function(tbl) + local str = render_internal(tbl, 0) + return '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n' .. str end -marigold.decode_query = function(str) - local tbl = {} - local cleanString = function(str) - return marigold.decode_percent( - string.gsub(str, "+", " ") - ) + +-- built-in svg types + +local function set(tbl) + local s = {} + for _, v in ipairs(tbl) do + s[v] = true end + return s +end - for k, v in string.gmatch(str, "([^=]-)=([^&]*)&?") do - tbl[cleanString(k)] = cleanString(v) +local function validate(tagname, valid, tbl) + local valid_set = set(valid) + -- inject the core svg attributes + valid_set.id = true + valid_set.tabindex = true + valid_set.lang = true + valid_set['xml:space'] = true + valid_set.class = true + valid_set.style = true + for k in pairs(tbl) do + if not valid_set[k] then return string.format( + "ERROR: attempted to set invalid attribute '%s' on tag of type %s", + k, tagname + ) end end + return nil +end + +local function maketag(tag, content, tbl, valid) + local t = marigold.h(tag, content, tbl) + local err = validate(tag, valid, t.attributes) + if err then return nil, err end + return t, nil +end - return tbl + +marigold.svg = function(tbl) + local tbl = tbl or {} + tbl.xmlns = 'http://www.w3.org/2000/svg' + local tag, err = maketag('svg', '', tbl, { 'xmlns', 'viewBox', 'width', 'height' }) + if err then error(err) end + return tag end + +marigold.g = function(tbl) + local tbl = tbl or {} + local tag, err = maketag('g', '', tbl, { 'transform' }) + if err then error(err) end + return tag +end + + +marigold.rect = function(tbl) + local tag, err = maketag('rect', '', tbl, { 'x', 'y', 'width', 'height', 'rx', 'ry', 'transform', }) + if err then error(err) end + return tag +end + + +marigold.text = function(tbl) +end + + + return marigold |