From b658c1f9650990259d7f970682f91c1dc0739c35 Mon Sep 17 00:00:00 2001 From: Michael Hatherly Date: Sun, 26 Nov 2023 22:50:06 +0000 Subject: [PATCH] Support `...` in element attributes (#16) For passing arbitrary attributes to elements. --- src/nodes/element.jl | 4 +++- src/nodes/function.jl | 4 ++-- src/symbol-swapping.jl | 15 +++++++++++++-- test/runtests.jl | 15 +++++++++++++++ test/templates.jl | 1 + test/templates/basic/splatted-props.1.txt | 1 + test/templates/basic/splatted-props.2.txt | 1 + test/templates/basic/splatted-props.3.txt | 1 + test/templates/basic/splatted-props.html | 12 ++++++++++++ 9 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 test/templates/basic/splatted-props.1.txt create mode 100644 test/templates/basic/splatted-props.2.txt create mode 100644 test/templates/basic/splatted-props.3.txt create mode 100644 test/templates/basic/splatted-props.html diff --git a/src/nodes/element.jl b/src/nodes/element.jl index bec7d83..e62bb31 100644 --- a/src/nodes/element.jl +++ b/src/nodes/element.jl @@ -21,7 +21,9 @@ end function expression(c::BuilderContext, a::Attribute) name = Symbol(a.name) - if a.dynamic + if name == :... + return Expr(:(...), Meta.parse(a.value)) + elseif a.dynamic return Expr(:(kw), name, Meta.parse(a.value)) elseif a.interpolate return Expr(:(kw), name, Meta.parse("\"\"\"$(a.value)\"\"\"")) diff --git a/src/nodes/function.jl b/src/nodes/function.jl index 5907d79..329ddbd 100644 --- a/src/nodes/function.jl +++ b/src/nodes/function.jl @@ -7,9 +7,9 @@ struct Prop function Prop(name, value) vararg = false - if endswith(name, "...") + if endswith(name, __SPECIAL_SPLAT_SYMBOL__) name == value || error("invalid syntax for '...' prop: $(name)...=$(value).") - name, _ = rsplit(name, "..."; limit = 2) + name, _ = rsplit(name, __SPECIAL_SPLAT_SYMBOL__; limit = 2) value = name vararg = true end diff --git a/src/symbol-swapping.jl b/src/symbol-swapping.jl index 2dd2563..c207ef3 100644 --- a/src/symbol-swapping.jl +++ b/src/symbol-swapping.jl @@ -1,8 +1,14 @@ const __SPECIAL_AT_SYMBOL__ = "__special_at_symbol__" const __SPECIAL_DOLLAR_SYMBOL__ = "__special_dollar_symbol__" +const __SPECIAL_SPLAT_SYMBOL__ = "__special_splat_symbol__" function _swap_special_symbols(s::String)::String - return _replace(s, "@" => __SPECIAL_AT_SYMBOL__, "\$" => __SPECIAL_DOLLAR_SYMBOL__) + return _replace( + s, + "@" => __SPECIAL_AT_SYMBOL__, + "\$" => __SPECIAL_DOLLAR_SYMBOL__, + "..." => __SPECIAL_SPLAT_SYMBOL__, + ) end function _restore_special_symbols(other) @@ -10,7 +16,12 @@ function _restore_special_symbols(other) end function _restore_special_symbols(s::AbstractString) - return _replace(s, __SPECIAL_AT_SYMBOL__ => "@", __SPECIAL_DOLLAR_SYMBOL__ => "\$") + return _replace( + s, + __SPECIAL_AT_SYMBOL__ => "@", + __SPECIAL_DOLLAR_SYMBOL__ => "\$", + __SPECIAL_SPLAT_SYMBOL__ => "...", + ) end @static if VERSION >= v"1.7" diff --git a/test/runtests.jl b/test/runtests.jl index 9adbb83..4bbaa4f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -198,6 +198,21 @@ end b = 10, ) + @test_reference joinpath(basic, "splatted-props.1.txt") render( + Templates.var"splatted-props"; + props = (;), + ) + + @test_reference joinpath(basic, "splatted-props.2.txt") render( + Templates.var"splatted-props"; + props = (; value = 2), + ) + + @test_reference joinpath(basic, "splatted-props.3.txt") render( + Templates.var"splatted-props"; + props = (; option = "option"), + ) + @test_throws_st UndefVarError render(Templates.var"file-and-line-info-1") [ "file-and-line-info.html:2", "file-and-line-info.html:1", diff --git a/test/templates.jl b/test/templates.jl index b7beea4..c9f0d29 100644 --- a/test/templates.jl +++ b/test/templates.jl @@ -15,6 +15,7 @@ template"templates/basic/layout-usage.html" template"templates/basic/special-symbols.html" template"templates/basic/custom-elements.html" template"templates/basic/splat.html" +template"templates/basic/splatted-props.html" template"templates/basic/file-and-line-info.html" module Complex diff --git a/test/templates/basic/splatted-props.1.txt b/test/templates/basic/splatted-props.1.txt new file mode 100644 index 0000000..f2048d7 --- /dev/null +++ b/test/templates/basic/splatted-props.1.txt @@ -0,0 +1 @@ +
1
\ No newline at end of file diff --git a/test/templates/basic/splatted-props.2.txt b/test/templates/basic/splatted-props.2.txt new file mode 100644 index 0000000..a0f4534 --- /dev/null +++ b/test/templates/basic/splatted-props.2.txt @@ -0,0 +1 @@ +
2
\ No newline at end of file diff --git a/test/templates/basic/splatted-props.3.txt b/test/templates/basic/splatted-props.3.txt new file mode 100644 index 0000000..cc31309 --- /dev/null +++ b/test/templates/basic/splatted-props.3.txt @@ -0,0 +1 @@ +
1
\ No newline at end of file diff --git a/test/templates/basic/splatted-props.html b/test/templates/basic/splatted-props.html new file mode 100644 index 0000000..dde960d --- /dev/null +++ b/test/templates/basic/splatted-props.html @@ -0,0 +1,12 @@ + +
+ +
+
+
+ + + + + + \ No newline at end of file