Plugin architecture for parsers
This commit is contained in:
parent
3d620c7b07
commit
f8f1ec623f
261
lib/temple.ex
261
lib/temple.ex
|
@ -122,266 +122,11 @@ defmodule Temple do
|
|||
end
|
||||
end
|
||||
|
||||
defmodule Private do
|
||||
@moduledoc false
|
||||
@aliases Application.get_env(:temple, :aliases, [])
|
||||
|
||||
@nonvoid_elements ~w[
|
||||
head title style script
|
||||
noscript template
|
||||
body section nav article aside h1 h2 h3 h4 h5 h6
|
||||
header footer address main
|
||||
p pre blockquote ol ul li dl dt dd figure figcaption div
|
||||
a em strong small s cite q dfn abbr data time code var samp kbd
|
||||
sub sup i b u mark ruby rt rp bdi bdo span
|
||||
ins del
|
||||
iframe object video audio canvas
|
||||
map
|
||||
table caption colgroup tbody thead tfoot tr td th
|
||||
form fieldset legend label button select datalist optgroup
|
||||
option textarea output progress meter
|
||||
details summary menuitem menu
|
||||
html
|
||||
]a
|
||||
|
||||
@nonvoid_elements_aliases Enum.map(@nonvoid_elements, fn el ->
|
||||
Keyword.get(@aliases, el, el)
|
||||
end)
|
||||
@nonvoid_elements_lookup Enum.map(@nonvoid_elements, fn el ->
|
||||
{Keyword.get(@aliases, el, el), el}
|
||||
end)
|
||||
|
||||
@void_elements ~w[
|
||||
meta link base
|
||||
area br col embed hr img input keygen param source track wbr
|
||||
]a
|
||||
|
||||
@void_elements_aliases Enum.map(@void_elements, fn el -> Keyword.get(@aliases, el, el) end)
|
||||
@void_elements_lookup Enum.map(@void_elements, fn el ->
|
||||
{Keyword.get(@aliases, el, el), el}
|
||||
end)
|
||||
|
||||
def snake_to_kebab(stringable),
|
||||
do:
|
||||
stringable |> to_string() |> String.replace_trailing("_", "") |> String.replace("_", "-")
|
||||
|
||||
def kebab_to_snake(stringable),
|
||||
do: stringable |> to_string() |> String.replace("-", "_")
|
||||
|
||||
def compile_attrs([]), do: ""
|
||||
|
||||
def compile_attrs([attrs]) when is_list(attrs) do
|
||||
compile_attrs(attrs)
|
||||
end
|
||||
|
||||
def compile_attrs(attrs) do
|
||||
for {name, value} <- attrs, into: "" do
|
||||
name = snake_to_kebab(name)
|
||||
|
||||
case value do
|
||||
{_, _, _} = macro ->
|
||||
" " <> name <> "=\"<%= " <> Macro.to_string(macro) <> " %>\""
|
||||
|
||||
value ->
|
||||
" " <> name <> "=\"" <> to_string(value) <> "\""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def split_args(nil), do: {[], []}
|
||||
|
||||
def split_args(args) do
|
||||
{do_and_else, args} =
|
||||
args
|
||||
|> Enum.split_with(fn
|
||||
arg when is_list(arg) ->
|
||||
(Keyword.keys(arg) -- [:do, :else]) |> Enum.count() == 0
|
||||
|
||||
_ ->
|
||||
false
|
||||
end)
|
||||
|
||||
{List.flatten(do_and_else), args}
|
||||
end
|
||||
|
||||
def split_on_fn([{:fn, _, _} = func | rest], {args, _, args2}) do
|
||||
split_on_fn(rest, {args, func, args2})
|
||||
end
|
||||
|
||||
def split_on_fn([arg | rest], {args, nil, args2}) do
|
||||
split_on_fn(rest, {[arg | args], nil, args2})
|
||||
end
|
||||
|
||||
def split_on_fn([arg | rest], {args, func, args2}) do
|
||||
split_on_fn(rest, {args, func, [arg | args2]})
|
||||
end
|
||||
|
||||
def split_on_fn([], {args, func, args2}) do
|
||||
{Enum.reverse(args), func, Enum.reverse(args2)}
|
||||
end
|
||||
|
||||
def pop_compact?([]), do: {false, []}
|
||||
def pop_compact?([args]) when is_list(args), do: pop_compact?(args)
|
||||
|
||||
def pop_compact?(args) do
|
||||
Keyword.pop(args, :compact, false)
|
||||
end
|
||||
|
||||
def traverse(buffer, {:__block__, _meta, block}) do
|
||||
traverse(buffer, block)
|
||||
end
|
||||
|
||||
def traverse(buffer, {name, meta, args} = macro) do
|
||||
{do_and_else, args} =
|
||||
args
|
||||
|> split_args()
|
||||
|
||||
includes_fn? = args |> Enum.any?(fn x -> match?({:fn, _, _}, x) end)
|
||||
|
||||
case name do
|
||||
{:., _, [{:__aliases__, _, [:Temple]}, name]} when name in @nonvoid_elements_aliases ->
|
||||
{do_and_else, args} =
|
||||
case args do
|
||||
[args] ->
|
||||
{do_value, args} = Keyword.pop(args, :do)
|
||||
|
||||
do_and_else = Keyword.put_new(do_and_else, :do, do_value)
|
||||
|
||||
{do_and_else, args}
|
||||
|
||||
_ ->
|
||||
{do_and_else, args}
|
||||
end
|
||||
|
||||
name = @nonvoid_elements_lookup[name]
|
||||
|
||||
{compact?, args} = pop_compact?(args)
|
||||
|
||||
Buffer.put(buffer, "<#{name}#{compile_attrs(args)}>")
|
||||
unless compact?, do: Buffer.put(buffer, "\n")
|
||||
traverse(buffer, do_and_else[:do])
|
||||
if compact?, do: Buffer.remove_new_line(buffer)
|
||||
Buffer.put(buffer, "</#{name}>")
|
||||
Buffer.put(buffer, "\n")
|
||||
|
||||
{:., _, [{:__aliases__, _, [:Temple]}, name]} when name in @void_elements_aliases ->
|
||||
name = @void_elements_lookup[name]
|
||||
|
||||
Buffer.put(buffer, "<#{name}#{compile_attrs(args)}>")
|
||||
Buffer.put(buffer, "\n")
|
||||
|
||||
name when name in @nonvoid_elements_aliases ->
|
||||
{do_and_else, args} =
|
||||
case args do
|
||||
[args] ->
|
||||
{do_value, args} = Keyword.pop(args, :do)
|
||||
|
||||
do_and_else = Keyword.put_new(do_and_else, :do, do_value)
|
||||
|
||||
{do_and_else, args}
|
||||
|
||||
_ ->
|
||||
{do_and_else, args}
|
||||
end
|
||||
|
||||
name = @nonvoid_elements_lookup[name]
|
||||
|
||||
{compact?, args} = pop_compact?(args)
|
||||
|
||||
Buffer.put(buffer, "<#{name}#{compile_attrs(args)}>")
|
||||
unless compact?, do: Buffer.put(buffer, "\n")
|
||||
traverse(buffer, do_and_else[:do])
|
||||
if compact?, do: Buffer.remove_new_line(buffer)
|
||||
Buffer.put(buffer, "</#{name}>")
|
||||
Buffer.put(buffer, "\n")
|
||||
|
||||
name when name in @void_elements_aliases ->
|
||||
name = @void_elements_lookup[name]
|
||||
|
||||
Buffer.put(buffer, "<#{name}#{compile_attrs(args)}>")
|
||||
Buffer.put(buffer, "\n")
|
||||
|
||||
name when includes_fn? ->
|
||||
{args, func_arg, args2} = split_on_fn(args, {[], nil, []})
|
||||
|
||||
{func, _, [{arrow, _, [[{arg, _, _}], block]}]} = func_arg
|
||||
|
||||
Buffer.put(
|
||||
buffer,
|
||||
"<%= " <>
|
||||
to_string(name) <>
|
||||
" " <>
|
||||
(Enum.map(args, &Macro.to_string(&1)) |> Enum.join(", ")) <>
|
||||
", " <>
|
||||
to_string(func) <> " " <> to_string(arg) <> " " <> to_string(arrow) <> " %>"
|
||||
)
|
||||
|
||||
Buffer.put(buffer, "\n")
|
||||
|
||||
traverse(buffer, block)
|
||||
|
||||
if Enum.any?(args2) do
|
||||
Buffer.put(
|
||||
buffer,
|
||||
"<% end, " <>
|
||||
(Enum.map(args2, fn arg -> Macro.to_string(arg) end)
|
||||
|> Enum.join(", ")) <> " %>"
|
||||
)
|
||||
|
||||
Buffer.put(buffer, "\n")
|
||||
else
|
||||
Buffer.put(buffer, "<% end %>")
|
||||
Buffer.put(buffer, "\n")
|
||||
end
|
||||
|
||||
name when name in [:for, :if, :unless] ->
|
||||
Buffer.put(buffer, "<%= " <> Macro.to_string({name, meta, args}) <> " do %>")
|
||||
Buffer.put(buffer, "\n")
|
||||
|
||||
traverse(buffer, do_and_else[:do])
|
||||
|
||||
if Keyword.has_key?(do_and_else, :else) do
|
||||
Buffer.put(buffer, "<% else %>")
|
||||
Buffer.put(buffer, "\n")
|
||||
traverse(buffer, do_and_else[:else])
|
||||
end
|
||||
|
||||
Buffer.put(buffer, "<% end %>")
|
||||
Buffer.put(buffer, "\n")
|
||||
|
||||
name when name in [:=] ->
|
||||
Buffer.put(buffer, "<% " <> Macro.to_string(macro) <> " %>")
|
||||
Buffer.put(buffer, "\n")
|
||||
traverse(buffer, do_and_else[:do])
|
||||
|
||||
_ ->
|
||||
Buffer.put(buffer, "<%= " <> Macro.to_string(macro) <> " %>")
|
||||
Buffer.put(buffer, "\n")
|
||||
traverse(buffer, do_and_else[:do])
|
||||
end
|
||||
end
|
||||
|
||||
def traverse(buffer, [first | rest]) do
|
||||
traverse(buffer, first)
|
||||
|
||||
traverse(buffer, rest)
|
||||
end
|
||||
|
||||
def traverse(buffer, text) when is_binary(text) do
|
||||
Buffer.put(buffer, text)
|
||||
Buffer.put(buffer, "\n")
|
||||
end
|
||||
|
||||
def traverse(_buffer, arg) when arg in [nil, []] do
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
defmacro temple([do: block] = _block) do
|
||||
{:ok, buffer} = Buffer.start_link()
|
||||
|
||||
buffer
|
||||
|> Temple.Private.traverse(block)
|
||||
|> Temple.Parser.Private.traverse(block)
|
||||
|
||||
markup = Buffer.get(buffer)
|
||||
|
||||
|
@ -399,7 +144,7 @@ defmodule Temple do
|
|||
{:ok, buffer} = Buffer.start_link()
|
||||
|
||||
buffer
|
||||
|> Temple.Private.traverse(unquote(block))
|
||||
|> Temple.Parser.Private.traverse(unquote(block))
|
||||
|
||||
markup = Buffer.get(buffer)
|
||||
|
||||
|
@ -413,7 +158,7 @@ defmodule Temple do
|
|||
{:ok, buffer} = Buffer.start_link()
|
||||
|
||||
buffer
|
||||
|> Temple.Private.traverse(block)
|
||||
|> Temple.Parser.Private.traverse(block)
|
||||
|
||||
markup = Buffer.get(buffer)
|
||||
|
||||
|
|
375
lib/temple/parser.ex
Normal file
375
lib/temple/parser.ex
Normal file
|
@ -0,0 +1,375 @@
|
|||
defmodule Temple.Parser do
|
||||
alias Temple.Buffer
|
||||
|
||||
@aliases Application.get_env(:temple, :aliases, [])
|
||||
|
||||
@nonvoid_elements ~w[
|
||||
head title style script
|
||||
noscript template
|
||||
body section nav article aside h1 h2 h3 h4 h5 h6
|
||||
header footer address main
|
||||
p pre blockquote ol ul li dl dt dd figure figcaption div
|
||||
a em strong small s cite q dfn abbr data time code var samp kbd
|
||||
sub sup i b u mark ruby rt rp bdi bdo span
|
||||
ins del
|
||||
iframe object video audio canvas
|
||||
map
|
||||
table caption colgroup tbody thead tfoot tr td th
|
||||
form fieldset legend label button select datalist optgroup
|
||||
option textarea output progress meter
|
||||
details summary menuitem menu
|
||||
html
|
||||
]a
|
||||
|
||||
@nonvoid_elements_aliases Enum.map(@nonvoid_elements, fn el ->
|
||||
Keyword.get(@aliases, el, el)
|
||||
end)
|
||||
@nonvoid_elements_lookup Enum.map(@nonvoid_elements, fn el ->
|
||||
{Keyword.get(@aliases, el, el), el}
|
||||
end)
|
||||
|
||||
@void_elements ~w[
|
||||
meta link base
|
||||
area br col embed hr img input keygen param source track wbr
|
||||
]a
|
||||
|
||||
@void_elements_aliases Enum.map(@void_elements, fn el -> Keyword.get(@aliases, el, el) end)
|
||||
@void_elements_lookup Enum.map(@void_elements, fn el ->
|
||||
{Keyword.get(@aliases, el, el), el}
|
||||
end)
|
||||
|
||||
defmodule Private do
|
||||
@moduledoc false
|
||||
|
||||
def snake_to_kebab(stringable),
|
||||
do:
|
||||
stringable |> to_string() |> String.replace_trailing("_", "") |> String.replace("_", "-")
|
||||
|
||||
def kebab_to_snake(stringable),
|
||||
do: stringable |> to_string() |> String.replace("-", "_")
|
||||
|
||||
def compile_attrs([]), do: ""
|
||||
|
||||
def compile_attrs([attrs]) when is_list(attrs) do
|
||||
compile_attrs(attrs)
|
||||
end
|
||||
|
||||
def compile_attrs(attrs) do
|
||||
for {name, value} <- attrs, into: "" do
|
||||
name = snake_to_kebab(name)
|
||||
|
||||
case value do
|
||||
{_, _, _} = macro ->
|
||||
" " <> name <> "=\"<%= " <> Macro.to_string(macro) <> " %>\""
|
||||
|
||||
value ->
|
||||
" " <> name <> "=\"" <> to_string(value) <> "\""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def split_args(nil), do: {[], []}
|
||||
|
||||
def split_args(args) do
|
||||
{do_and_else, args} =
|
||||
args
|
||||
|> Enum.split_with(fn
|
||||
arg when is_list(arg) ->
|
||||
(Keyword.keys(arg) -- [:do, :else]) |> Enum.count() == 0
|
||||
|
||||
_ ->
|
||||
false
|
||||
end)
|
||||
|
||||
{List.flatten(do_and_else), args}
|
||||
end
|
||||
|
||||
def split_on_fn([{:fn, _, _} = func | rest], {args, _, args2}) do
|
||||
split_on_fn(rest, {args, func, args2})
|
||||
end
|
||||
|
||||
def split_on_fn([arg | rest], {args, nil, args2}) do
|
||||
split_on_fn(rest, {[arg | args], nil, args2})
|
||||
end
|
||||
|
||||
def split_on_fn([arg | rest], {args, func, args2}) do
|
||||
split_on_fn(rest, {args, func, [arg | args2]})
|
||||
end
|
||||
|
||||
def split_on_fn([], {args, func, args2}) do
|
||||
{Enum.reverse(args), func, Enum.reverse(args2)}
|
||||
end
|
||||
|
||||
def pop_compact?([]), do: {false, []}
|
||||
def pop_compact?([args]) when is_list(args), do: pop_compact?(args)
|
||||
|
||||
def pop_compact?(args) do
|
||||
Keyword.pop(args, :compact, false)
|
||||
end
|
||||
|
||||
def traverse(buffer, {:__block__, _meta, block}) do
|
||||
traverse(buffer, block)
|
||||
end
|
||||
|
||||
def traverse(buffer, {_name, _meta, _args} = macro) do
|
||||
Temple.Parser.parsers()
|
||||
|> Enum.reduce_while(nil, fn parser, _ ->
|
||||
if parser.applicable?.(macro) do
|
||||
parser.parse.(macro, buffer)
|
||||
{:halt, nil}
|
||||
else
|
||||
{:cont, nil}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
def traverse(buffer, [first | rest]) do
|
||||
traverse(buffer, first)
|
||||
|
||||
traverse(buffer, rest)
|
||||
end
|
||||
|
||||
def traverse(buffer, text) when is_binary(text) do
|
||||
Buffer.put(buffer, text)
|
||||
Buffer.put(buffer, "\n")
|
||||
end
|
||||
|
||||
def traverse(_buffer, arg) when arg in [nil, []] do
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def parsers(),
|
||||
do: [
|
||||
%{
|
||||
name: :temple_namespace_nonvoid,
|
||||
applicable?: fn {name, _meta, _args} ->
|
||||
try do
|
||||
{:., _, [{:__aliases__, _, [:Temple]}, name]} = name
|
||||
name in @nonvoid_elements_aliases
|
||||
rescue
|
||||
MatchError ->
|
||||
false
|
||||
end
|
||||
end,
|
||||
parse: fn {name, _meta, args}, buffer ->
|
||||
import Temple.Parser.Private
|
||||
{:., _, [{:__aliases__, _, [:Temple]}, name]} = name
|
||||
|
||||
{do_and_else, args} =
|
||||
args
|
||||
|> split_args()
|
||||
|
||||
{do_and_else, args} =
|
||||
case args do
|
||||
[args] ->
|
||||
{do_value, args} = Keyword.pop(args, :do)
|
||||
|
||||
do_and_else = Keyword.put_new(do_and_else, :do, do_value)
|
||||
|
||||
{do_and_else, args}
|
||||
|
||||
_ ->
|
||||
{do_and_else, args}
|
||||
end
|
||||
|
||||
name = @nonvoid_elements_lookup[name]
|
||||
|
||||
{compact?, args} = pop_compact?(args)
|
||||
|
||||
Buffer.put(buffer, "<#{name}#{compile_attrs(args)}>")
|
||||
unless compact?, do: Buffer.put(buffer, "\n")
|
||||
traverse(buffer, do_and_else[:do])
|
||||
if compact?, do: Buffer.remove_new_line(buffer)
|
||||
Buffer.put(buffer, "</#{name}>")
|
||||
Buffer.put(buffer, "\n")
|
||||
end
|
||||
},
|
||||
%{
|
||||
name: :temple_namespace_void,
|
||||
applicable?: fn {name, _meta, _args} ->
|
||||
try do
|
||||
{:., _, [{:__aliases__, _, [:Temple]}, name]} = name
|
||||
name in @void_elements_aliases
|
||||
rescue
|
||||
MatchError ->
|
||||
false
|
||||
end
|
||||
end,
|
||||
parse: fn {name, _, args}, buffer ->
|
||||
import Temple.Parser.Private
|
||||
{:., _, [{:__aliases__, _, [:Temple]}, name]} = name
|
||||
|
||||
{_do_and_else, args} =
|
||||
args
|
||||
|> split_args()
|
||||
|
||||
name = @void_elements_lookup[name]
|
||||
|
||||
Buffer.put(buffer, "<#{name}#{compile_attrs(args)}>")
|
||||
Buffer.put(buffer, "\n")
|
||||
end
|
||||
},
|
||||
%{
|
||||
name: :nonvoid_elements_aliases,
|
||||
applicable?: fn {name, _, _} ->
|
||||
name in @nonvoid_elements_aliases
|
||||
end,
|
||||
parse: fn {name, _, args}, buffer ->
|
||||
import Temple.Parser.Private
|
||||
|
||||
{do_and_else, args} =
|
||||
args
|
||||
|> split_args()
|
||||
|
||||
{do_and_else, args} =
|
||||
case args do
|
||||
[args] ->
|
||||
{do_value, args} = Keyword.pop(args, :do)
|
||||
|
||||
do_and_else = Keyword.put_new(do_and_else, :do, do_value)
|
||||
|
||||
{do_and_else, args}
|
||||
|
||||
_ ->
|
||||
{do_and_else, args}
|
||||
end
|
||||
|
||||
name = @nonvoid_elements_lookup[name]
|
||||
|
||||
{compact?, args} = pop_compact?(args)
|
||||
|
||||
Buffer.put(buffer, "<#{name}#{compile_attrs(args)}>")
|
||||
unless compact?, do: Buffer.put(buffer, "\n")
|
||||
traverse(buffer, do_and_else[:do])
|
||||
if compact?, do: Buffer.remove_new_line(buffer)
|
||||
Buffer.put(buffer, "</#{name}>")
|
||||
Buffer.put(buffer, "\n")
|
||||
end
|
||||
},
|
||||
%{
|
||||
name: :void_elements_aliases,
|
||||
applicable?: fn {name, _, _} ->
|
||||
name in @void_elements_aliases
|
||||
end,
|
||||
parse: fn {name, _, args}, buffer ->
|
||||
import Temple.Parser.Private
|
||||
|
||||
{_do_and_else, args} =
|
||||
args
|
||||
|> split_args()
|
||||
|
||||
name = @void_elements_lookup[name]
|
||||
|
||||
Buffer.put(buffer, "<#{name}#{compile_attrs(args)}>")
|
||||
Buffer.put(buffer, "\n")
|
||||
end
|
||||
},
|
||||
%{
|
||||
name: :anonymous_functions,
|
||||
applicable?: fn {_, _, args} ->
|
||||
import Temple.Parser.Private, only: [split_args: 1]
|
||||
|
||||
args |> split_args() |> elem(1) |> Enum.any?(fn x -> match?({:fn, _, _}, x) end)
|
||||
end,
|
||||
parse: fn {name, _, args}, buffer ->
|
||||
import Temple.Parser.Private
|
||||
|
||||
{_do_and_else, args} =
|
||||
args
|
||||
|> split_args()
|
||||
|
||||
{args, func_arg, args2} = split_on_fn(args, {[], nil, []})
|
||||
|
||||
{func, _, [{arrow, _, [[{arg, _, _}], block]}]} = func_arg
|
||||
|
||||
Buffer.put(
|
||||
buffer,
|
||||
"<%= " <>
|
||||
to_string(name) <>
|
||||
" " <>
|
||||
(Enum.map(args, &Macro.to_string(&1)) |> Enum.join(", ")) <>
|
||||
", " <>
|
||||
to_string(func) <> " " <> to_string(arg) <> " " <> to_string(arrow) <> " %>"
|
||||
)
|
||||
|
||||
Buffer.put(buffer, "\n")
|
||||
|
||||
traverse(buffer, block)
|
||||
|
||||
if Enum.any?(args2) do
|
||||
Buffer.put(
|
||||
buffer,
|
||||
"<% end, " <>
|
||||
(Enum.map(args2, fn arg -> Macro.to_string(arg) end)
|
||||
|> Enum.join(", ")) <> " %>"
|
||||
)
|
||||
|
||||
Buffer.put(buffer, "\n")
|
||||
else
|
||||
Buffer.put(buffer, "<% end %>")
|
||||
Buffer.put(buffer, "\n")
|
||||
end
|
||||
end
|
||||
},
|
||||
%{
|
||||
name: :for_if_unless,
|
||||
applicable?: fn {name, _, _} ->
|
||||
name in [:for, :if, :unless]
|
||||
end,
|
||||
parse: fn {name, meta, args}, buffer ->
|
||||
import Temple.Parser.Private
|
||||
|
||||
{do_and_else, args} =
|
||||
args
|
||||
|> split_args()
|
||||
|
||||
Buffer.put(buffer, "<%= " <> Macro.to_string({name, meta, args}) <> " do %>")
|
||||
Buffer.put(buffer, "\n")
|
||||
|
||||
traverse(buffer, do_and_else[:do])
|
||||
|
||||
if Keyword.has_key?(do_and_else, :else) do
|
||||
Buffer.put(buffer, "<% else %>")
|
||||
Buffer.put(buffer, "\n")
|
||||
traverse(buffer, do_and_else[:else])
|
||||
end
|
||||
|
||||
Buffer.put(buffer, "<% end %>")
|
||||
Buffer.put(buffer, "\n")
|
||||
end
|
||||
},
|
||||
%{
|
||||
name: :match,
|
||||
applicable?: fn {name, _, _} ->
|
||||
name in [:=]
|
||||
end,
|
||||
parse: fn {_, _, args} = macro, buffer ->
|
||||
import Temple.Parser.Private
|
||||
|
||||
{do_and_else, _args} =
|
||||
args
|
||||
|> split_args()
|
||||
|
||||
Buffer.put(buffer, "<% " <> Macro.to_string(macro) <> " %>")
|
||||
Buffer.put(buffer, "\n")
|
||||
traverse(buffer, do_and_else[:do])
|
||||
end
|
||||
},
|
||||
%{
|
||||
name: :default,
|
||||
applicable?: fn _ -> true end,
|
||||
parse: fn {_, _, args} = macro, buffer ->
|
||||
import Temple.Parser.Private
|
||||
|
||||
{do_and_else, _args} =
|
||||
args
|
||||
|> split_args()
|
||||
|
||||
Buffer.put(buffer, "<%= " <> Macro.to_string(macro) <> " %>")
|
||||
Buffer.put(buffer, "\n")
|
||||
traverse(buffer, do_and_else[:do])
|
||||
end
|
||||
}
|
||||
]
|
||||
end
|
Reference in a new issue