summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2023-08-18 01:42:20 -0500
committersanine <sanine.not@pm.me>2023-08-18 01:42:20 -0500
commit83448304527d8a1dde233f2f33b98124bced5f88 (patch)
treee0992f3083c5fbfbe84c319fd9f0a5fc1a9c64d2
parent9363bfcbd23b4652af40bf56273ade6f395539f4 (diff)
implement some basic svg rendering
-rw-r--r--marigold.lua101
-rwxr-xr-xtest.lua106
2 files changed, 103 insertions, 104 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
diff --git a/test.lua b/test.lua
index e359c7e..47c7fed 100755
--- a/test.lua
+++ b/test.lua
@@ -1,6 +1,6 @@
-#!/usr/bin/lua
+#!/usr/bin/env lua5.1
-local marigold = require 'marigold'
+local svg = require 'marigold'
function test(description, func)
io.write(description .. ': ')
@@ -15,45 +15,8 @@ function test(description, func)
end
-test("marigold.get_metavars correctly calls os.getenv", function()
- -- mock os.getenv
- local old_getenv = os.getenv
- local env_tbl = {
- AUTH_TYPE = 'some auth type',
- CONTENT_LENGTH = 'a zillion',
- GATEWAY_INTERFACE = 'idk, something',
- PATH_INFO = 'youll see, its a secret',
- PATH_TRANSLATED = 'i told you its a secret!',
- QUERY_STRING = 'which string do you want?',
- REMOTE_ADDR = 'probably somewhere in nunavut',
- REMOTE_HOST = 'woah wait are we talking about parasites?',
- REMOTE_IDENT = 'are you a cop?',
- REMOTE_USER = 'seriously, you have to tell me if you are',
- REQUEST_METHOD = 'uhh, to do what?',
- SCRIPT_NAME = 'pretty sure this is hamlet',
- SERVER_NAME = 'this isnt a restaurant',
- SERVER_PORT = 'what, like a ship?',
- SERVER_PROTOCOL = 'no really, not a restaurant',
- SERVER_SOFTWARE = 'not familiar with that dish...',
- }
- os.getenv = function(varname) return env_tbl[varname] end
-
- -- actually call the function
- metavars = marigold.get_metavars()
-
- assert(type(metavars) == 'table')
- for k, v in pairs(env_tbl) do
- assert(metavars[string.lower(k)])
- assert(metavars[string.lower(k)] == env_tbl[k])
- end
-
- -- restore os.getenv
- os.getenv = old_getenv
-end)
-
-
-test("marigold.h produces a correct basic tag", function()
- local h = marigold.h
+test("svg.h produces a correct basic tag", function()
+ local h = svg.h
local h1 = h('h1', 'hello, world!')
assert(type(h1) == 'table')
assert(h1.tag == 'h1')
@@ -66,8 +29,8 @@ test("marigold.h produces a correct basic tag", function()
end)
-test("marigold.h correctly adds children", function()
- local h = marigold.h
+test("svg.h correctly adds children", function()
+ local h = svg.h
local div = h('div', "some stuff", {
h('p', "the first paragraph"),
h('p', "the second paragraph"),
@@ -87,8 +50,8 @@ test("marigold.h correctly adds children", function()
end)
-test("marigold.h correctly ignores missing content", function()
- local h = marigold.h
+test("svg.h correctly ignores missing content", function()
+ local h = svg.h
local div = h('div', {
h('p', "the first paragraph"),
h('p', "the second paragraph"),
@@ -108,8 +71,8 @@ test("marigold.h correctly ignores missing content", function()
end)
-test("marigold.h correctly sets attributes and children", function()
- local h = marigold.h
+test("svg.h correctly sets attributes and children", function()
+ local h = svg.h
local div = h('div', {
id="root", class="blinking bold",
h('p', "the first paragraph"),
@@ -130,24 +93,24 @@ test("marigold.h correctly sets attributes and children", function()
end)
-test("marigold.html correctly renders basic html table", function()
+test("svg.render correctly renders basic render table", function()
local tbl = { tag='p', content='some paragraph', attributes={}, children={}}
- local html = marigold.html(tbl)
- assert(html == '<p>some paragraph</p>')
+ local render = svg.render(tbl)
+ assert(render == '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n<p>some paragraph</p>')
end)
-test("marigold.html correctly renders tag attributes", function()
+test("svg.render correctly renders tag attributes", function()
local tbl = {
tag='p', content='some paragraph',
attributes={ id='p1', class='blinking bold' },
children={}}
- local html = marigold.html(tbl)
- assert(html == '<p class="blinking bold" id="p1">some paragraph</p>')
+ local render = svg.render(tbl)
+ assert(render == '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n<p class="blinking bold" id="p1">some paragraph</p>')
end)
-test("marigold.html correctly renders children", function()
+test("svg.render correctly renders children", function()
local tbl = {
tag = 'div', content='', attributes = {id="root"},
children = {
@@ -156,27 +119,34 @@ test("marigold.html correctly renders children", function()
}
}
- local html = marigold.html(tbl)
- assert(html == [[<div id="root">
+ local render = svg.render(tbl)
+ assert(render == [[<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<div id="root">
<p class="bold">p1</p>
<p>p2</p>
</div>]])
end)
-test("marigold.decode_percent correctly decodes percent-encoded strings", function()
- local str = '%20%21%23%24%25%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D'
- assert(marigold.decode_percent(str) == " !#$%&'()*+,/:;=?@[]")
- assert(marigold.decode_percent('%25+%2b') == '%++')
+
+
+test("svg.svg correctly has xmlns attribute set", function()
+ local tbl = svg.svg()
+ assert(tbl.tag == 'svg')
+ assert(tbl.content == '')
+ assert(tbl.attributes.xmlns == 'http://www.w3.org/2000/svg')
+ assert(#tbl.children == 0)
end)
-test("marigold.decode_query correctly obtains data", function()
- local tbl
- tbl = marigold.decode_query('')
- tbl = marigold.decode_query('name=john')
- assert(tbl.name == 'john')
- tbl = marigold.decode_query('string=hello%2C+world%21&name=jane')
- assert(tbl.string == 'hello, world!')
- assert(tbl.name == 'jane')
+test("svg.g can set transform attribute", function()
+ local tbl = svg.g{
+ transform = "rotate(45deg)",
+ svg.g(),
+ svg.g(),
+ }
+ assert(tbl.tag == 'g')
+ assert(tbl.content == '')
+ assert(tbl.attributes.transform == 'rotate(45deg)')
+ assert(#tbl.children == 2)
end)