Skip to content

Instantly share code, notes, and snippets.

@benjamintanweihao
Created July 14, 2016 09:37
Show Gist options
  • Select an option

  • Save benjamintanweihao/76d34933a09c094308f168c0f61eec11 to your computer and use it in GitHub Desktop.

Select an option

Save benjamintanweihao/76d34933a09c094308f168c0f61eec11 to your computer and use it in GitHub Desktop.
defmodule Html do
defmacro markup(do: inner) do
quote do
{:ok, var!(buffer, Html)} = start_buffer
unquote(inner)
result = get_buffer(var!(buffer, Html))
stop_buffer(var!(buffer, Html))
result
end
end
for tag <- [:article, :div, :h1, :h2] do
defmacro unquote(tag)(do: inner) do
IO.inspect tag # <- This will not work because we cannot see `tag`
t = unquote(tag) # Store name of tag in `t` because tag is an AST.
quote do
tag(unquote(t), do: unquote(inner)) # We need to unquote again because we are in a quote
end
end
end
defmacro tag(name, do: inner) do
quote do
put_buffer(var!(buffer, Html), "<#{unquote(name)}>")
unquote(inner)
put_buffer(var!(buffer, Html), "</#{unquote(name)}>")
end
end
defmacro text(text) do
quote do
put_buffer(var!(buffer, Html), unquote(text))
end
end
def start_buffer do
Agent.start_link(fn -> [] end)
end
def put_buffer(pid, buffer) do
Agent.update(pid, &[buffer|&1])
end
def get_buffer(pid) do
Agent.get(pid, &(&1)) |> Enum.reverse |> Enum.join
end
def stop_buffer(pid) do
Agent.stop(pid)
end
end
defmodule Foo do
import Html
m = markup do
div do
h1 do
text "OHAI"
end
article do
h2 do
text "KTHXBAI"
end
end
end
end
IO.puts "===================="
IO.inspect m
IO.puts "===================="
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment