diff --git a/lib/lazy_html.ex b/lib/lazy_html.ex
index 358b37e..2bfed79 100644
--- a/lib/lazy_html.ex
+++ b/lib/lazy_html.ex
@@ -498,7 +498,9 @@ defmodule LazyHTML do
"""
@spec html_escape(String.t()) :: String.t()
def html_escape(string) when is_binary(string) do
- LazyHTML.Tree.append_escaped(string, "")
+ string
+ |> LazyHTML.Tree.append_escaped([])
+ |> IO.iodata_to_binary()
end
# Access
diff --git a/lib/lazy_html/tree.ex b/lib/lazy_html/tree.ex
index 29edc32..ebd56c0 100644
--- a/lib/lazy_html/tree.ex
+++ b/lib/lazy_html/tree.ex
@@ -55,12 +55,11 @@ defmodule LazyHTML.Tree do
def to_html(tree, opts \\ []) when is_list(tree) and is_list(opts) do
opts = Keyword.validate!(opts, skip_whitespace_nodes: false)
- # We build the html by continuously appending to a result binary.
- # Appending to a binary is optimised by the runtime, so this
- # approach is memory efficient.
-
ctx = %{skip_whitespace_nodes: opts[:skip_whitespace_nodes], escape: true}
- to_html(tree, ctx, <<>>)
+
+ tree
+ |> to_html(ctx, [])
+ |> IO.iodata_to_binary()
end
@void_tags ~w(
@@ -73,17 +72,17 @@ defmodule LazyHTML.Tree do
defp to_html([], _ctx, html), do: html
defp to_html([{tag, attrs, children} | tree], ctx, html) do
- html = <>
+ html = [html, ?<, tag]
html = append_attrs(attrs, html)
if tag in @void_tags do
- html = <">>
+ html = [html, "/>"]
to_html(tree, ctx, html)
else
- html = <">>
+ html = [html, ?>]
escape_children = tag not in @no_escape_tags
html = to_html(children, %{ctx | escape: escape_children}, html)
- html = <">>
+ html = [html, "", tag, ?>]
to_html(tree, ctx, html)
end
end
@@ -94,15 +93,16 @@ defmodule LazyHTML.Tree do
end
defp to_html([{:comment, content} | tree], ctx, html) do
- to_html(tree, ctx, <">>)
+ html = [html, ""]
+ to_html(tree, ctx, html)
end
defp append_attrs([], html), do: html
defp append_attrs([{name, value} | attrs], html) do
- html = <>
+ html = [html, ?\s, name, ~S/="/]
html = append_escaped(value, html)
- html = <>
+ html = [html, ?"]
append_attrs(attrs, html)
end
@@ -116,7 +116,7 @@ defmodule LazyHTML.Tree do
defp append_text(<<_rest::binary>>, text, _whitespace_size, ctx, html)
when not ctx.escape,
- do: <>
+ do: [html, text]
defp append_text(<>, text, whitespace_size, ctx, html)
when ctx.escape,
@@ -141,12 +141,12 @@ defmodule LazyHTML.Tree do
defp append_escaped(<<>>, text, 0 = _offset, _size, html) do
# We scanned the whole text and there were no characters to escape,
# so we append the whole text.
- <>
+ [html, text]
end
defp append_escaped(<<>>, text, offset, size, html) do
chunk = binary_part(text, offset, size)
- <>
+ [html, chunk]
end
escapes = [
@@ -160,7 +160,7 @@ defmodule LazyHTML.Tree do
for {char, escaped} <- escapes do
defp append_escaped(<>, text, offset, size, html) do
chunk = binary_part(text, offset, size)
- html = <>
+ html = [html, chunk, unquote(escaped)]
append_escaped(rest, text, offset + size + 1, 0, html)
end
end