diff --git a/.rockspec b/.rockspec index fc054ec..1f37cf2 100644 --- a/.rockspec +++ b/.rockspec @@ -1,9 +1,9 @@ package = "luax" -version = "1.0.7-1" +version = "1.0.8-1" source = { - url = "https://github.com/syarul/luax/archive/refs/tags/v1.0.7.tar.gz", - dir = "luax-1.0.7" + url = "https://github.com/syarul/luax/archive/refs/tags/v1.0.8.tar.gz", + dir = "luax-1.0.8" } description = { summary = "HTML parse in Lua", diff --git a/README.md b/README.md index a3238e6..d4dc578 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ LuaX is Lua + XML Syntax extension with built-in decent parse. In retrospect it's akin to React JSX. - + [![Lua CI](https://github.com/syarul/luax/actions/workflows/lua.yml/badge.svg)](https://github.com/syarul/luax/actions/workflows/lua.yml) ## Decent Parser diff --git a/luax.lua b/luax.lua index 3c71bc3..ae77f97 100644 --- a/luax.lua +++ b/luax.lua @@ -27,6 +27,8 @@ function State:new() text_node_start = false, script_node = false, script_node_init = false, + style_node = false, + style_node_init = false, }, self) end @@ -48,7 +50,7 @@ function State:xml(level) if level ~= nil then return self.deep_node > level end return self.deep_node > 0 end -function State:not_str() return not self.deep_string and not self.deep_string_apos and not self.script_node end +function State:not_str() return not self.deep_string and not self.deep_string_apos and not self.script_node and not self.style_node end function State:toggle(key, bool) if bool ~= nil then self[key] = bool else self[key] = not self[key] end end @@ -122,6 +124,7 @@ local function decent_parser_ast(input) local tag_name_end = tag_range:match("([%w-]+)>", 0) local tag_doc_type = tag_range:match("<(%!%w+)", 0) local tag_script = tag_name and tag_name:match("script", 0) or tag_name_end and tag_name_end:match("script", 0) + local tag_style = tag_name and tag_name:match("style", 0) or tag_name_end and tag_name_end:match("style", 0) if tag_doc_type then tag_name = tag_doc_type:sub(2) s.doc_type = true @@ -148,6 +151,9 @@ local function decent_parser_ast(input) if tag_script then s.script_node_init = not s.script_node_init end + if tag_style then + s.style_node_init = not s.style_node_init + end if s:xml(1) then -- handle internal return function local ret = input:sub(s.pos-8, s.pos):gsub("%s\r\n", ""):sub(0, 6) == "return" @@ -189,9 +195,12 @@ local function decent_parser_ast(input) else s:conc(tok, 1) end - elseif tok == "<" and not s:not_str() and input:match("([%w-]+)>", s.pos) == "script" then + elseif tok == "<" and not s.style_node and not s:not_str() and input:match("([%w-]+)>", s.pos) == "script" then s:toggle("script_node") s:conc("]]") + elseif tok == "<" and not s.script_node and not s:not_str() and input:match("([%w-]+)>", s.pos) == "style" then + s:toggle("style_node") + s:conc("]]") elseif tok == '"' and s:xml() and not s.script_node then s:toggle("deep_string") s:conc(tok, 1) @@ -199,12 +208,14 @@ local function decent_parser_ast(input) s:toggle("deep_string_apos") s:conc(tok, 1) elseif tok == ">" and s:xml() and s:not_str() then - if not s.script_node_init and not s.text_node and s.is_tag and input:sub(s.pos - 1, s.pos - 1) ~= "/" then + if not s.style_node_init and not s.script_node_init and not s.text_node and s.is_tag and input:sub(s.pos - 1, s.pos - 1) ~= "/" then s:toggle("is_tag") s:toggle("text_node") s:conc("}") elseif s.script_node_init then - s:toggle("is_tag") + if s.is_tag then + s:toggle("is_tag") + end s:toggle("script_node_init") local trail = s.output:sub(#s.output - 10, #s.output):gsub("[%s\r\n]", "") if trail:sub(#trail) == "{" then @@ -213,12 +224,23 @@ local function decent_parser_ast(input) else s:conc("}") end + elseif s.style_node_init and not s.script_node_init then + if s.is_tag then + s:toggle("is_tag") + end + s:toggle("style_node_init") + local trail = s.output:sub(#s.output - 10, #s.output):gsub("[%s\r\n]", "") + if trail:sub(#trail) == "{" then + s:toggle("style_node") + s:conc("}, [[\n") + else + s:conc("}") + end else s.is_tag = not s.is_tag s:dec_deep_node() s:conc("})") end - if s.doc_type then s.doc_type = not s.doc_type local doc_type_params = s.output:sub(doc_type_start_pos, s.pos - 1) diff --git a/test/24_web_component_style.luax b/test/24_web_component_style.luax new file mode 100644 index 0000000..8e64a29 --- /dev/null +++ b/test/24_web_component_style.luax @@ -0,0 +1,44 @@ +return + +
+ + + +