From b1f7b0cbbfae20b3a392a71e92fd92adbe3c44cc Mon Sep 17 00:00:00 2001 From: shahrul Date: Fri, 18 Oct 2024 23:01:20 +0800 Subject: [PATCH] fix style block --- .rockspec | 6 ++--- README.md | 2 +- luax.lua | 32 +++++++++++++++++++---- test/24_web_component_style.luax | 44 ++++++++++++++++++++++++++++++++ test/test_ast.lua | 4 +++ test/test_spec.lua | 38 +++++++++++++++++++++++++++ 6 files changed, 117 insertions(+), 9 deletions(-) create mode 100644 test/24_web_component_style.luax 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. -Luarocks Package +Luarocks Package [![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("", 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("", s.pos) == "script" then + elseif tok == "<" and not s.style_node and not s:not_str() and input:match("", 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("", 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 + + + + + + + + + + \ No newline at end of file diff --git a/test/test_ast.lua b/test/test_ast.lua index 1af2fe3..91f3290 100644 --- a/test/test_ast.lua +++ b/test/test_ast.lua @@ -112,4 +112,8 @@ local st2 = require('test.23_web_component_test') h(st2) +local st4 = require('test.24_web_component_style') + +h(st4) + diff --git a/test/test_spec.lua b/test/test_spec.lua index 99cab60..94ce415 100644 --- a/test/test_spec.lua +++ b/test/test_spec.lua @@ -214,4 +214,42 @@ describe("LuaX", function() ]], h(st2)) end) + it("should return a HTML string when given XML like syntax with script tag", function() + local st3 = require('test.24_web_component_style') + assert.is.equal([[]], h(st3)) + end) + end)