diff --git a/lib/floki/raw_html.ex b/lib/floki/raw_html.ex
index 1d1d1ab2..9e6f0f9d 100644
--- a/lib/floki/raw_html.ex
+++ b/lib/floki/raw_html.ex
@@ -36,6 +36,7 @@ defmodule Floki.RawHTML do
def raw_html(html_tree, opts) do
opts = Keyword.validate!(opts, encode: use_default_encoder?(), pretty: false)
+ html_tree = List.wrap(html_tree)
encoder =
case opts[:encode] do
@@ -51,53 +52,36 @@ defmodule Floki.RawHTML do
self_closing_tags = self_closing_tags()
- IO.iodata_to_binary(build_raw_html(html_tree, [], encoder, padding, self_closing_tags))
+ html_tree
+ |> build_raw_html([], encoder, padding, self_closing_tags)
+ |> Enum.reverse()
+ |> IO.iodata_to_binary()
end
- defp build_raw_html([], html, _encoder, _padding, _self_closing_tags), do: html
+ defp build_raw_html([], acc, _encoder, _padding, _self_closing_tags), do: acc
- defp build_raw_html(string, _html, encoder, padding, _self_closing_tags)
+ defp build_raw_html([string | tail], acc, encoder, padding, self_closing_tags)
when is_binary(string) do
- leftpad_content(padding, encoder.(string))
+ content = leftpad_content(padding, encoder.(string))
+ acc = [content | acc]
+ build_raw_html(tail, acc, encoder, padding, self_closing_tags)
end
- defp build_raw_html(tuple, html, encoder, padding, self_closing_tags) when is_tuple(tuple),
- do: build_raw_html([tuple], html, encoder, padding, self_closing_tags)
-
- defp build_raw_html([string | tail], html, encoder, padding, self_closing_tags)
- when is_binary(string) do
- build_raw_html(
- tail,
- [html, leftpad_content(padding, encoder.(string))],
- encoder,
- padding,
- self_closing_tags
- )
+ defp build_raw_html([{:comment, comment} | tail], acc, encoder, padding, self_closing_tags) do
+ content = [leftpad(padding), ""]
+ acc = [content | acc]
+ build_raw_html(tail, acc, encoder, padding, self_closing_tags)
end
- defp build_raw_html([{:comment, comment} | tail], html, encoder, padding, self_closing_tags),
- do:
- build_raw_html(
- tail,
- [html, leftpad(padding), ""],
- encoder,
- padding,
- self_closing_tags
- )
-
- defp build_raw_html([{:pi, tag, attrs} | tail], html, encoder, padding, self_closing_tags) do
- build_raw_html(
- tail,
- [html, leftpad(padding), "", tag, tag_attrs(attrs, encoder), "?>"],
- encoder,
- padding,
- self_closing_tags
- )
+ defp build_raw_html([{:pi, tag, attrs} | tail], acc, encoder, padding, self_closing_tags) do
+ content = [leftpad(padding), "", tag, tag_attrs(attrs, encoder), "?>"]
+ acc = [content | acc]
+ build_raw_html(tail, acc, encoder, padding, self_closing_tags)
end
defp build_raw_html(
[{:doctype, type, public, system} | tail],
- html,
+ acc,
encoder,
padding,
self_closing_tags
@@ -109,23 +93,40 @@ defmodule Floki.RawHTML do
{public, system} -> [" PUBLIC \"", public, "\" \"", system | "\""]
end
- build_raw_html(
- tail,
- [html, leftpad(padding), ""],
- encoder,
- padding,
- self_closing_tags
- )
+ content = [leftpad(padding), ""]
+ acc = [content | acc]
+ build_raw_html(tail, acc, encoder, padding, self_closing_tags)
end
- defp build_raw_html([{type, attrs, children} | tail], html, encoder, padding, self_closing_tags) do
- build_raw_html(
- tail,
- [html | tag_for(type, attrs, children, encoder, padding, self_closing_tags)],
- encoder,
- padding,
- self_closing_tags
- )
+ defp build_raw_html([{type, attrs, children} | tail], acc, encoder, padding, self_closing_tags) do
+ encoder =
+ case type do
+ "script" -> @no_encoder
+ "style" -> @no_encoder
+ "title" -> @no_encoder
+ _ -> encoder
+ end
+
+ open_tag_content = [
+ tag_with_attrs(type, attrs, children, padding, encoder, self_closing_tags),
+ line_ending(padding)
+ ]
+
+ acc = [open_tag_content | acc]
+
+ acc =
+ case children do
+ [] ->
+ acc
+
+ _ ->
+ children = List.wrap(children)
+ build_raw_html(children, acc, encoder, pad_increase(padding), self_closing_tags)
+ end
+
+ close_tag_content = close_end_tag(type, children, padding, self_closing_tags)
+ acc = [close_tag_content | acc]
+ build_raw_html(tail, acc, encoder, padding, self_closing_tags)
end
defp tag_attrs(attr_list, encoder) do
@@ -171,29 +172,6 @@ defmodule Floki.RawHTML do
defp build_attrs(attr, _encoder), do: [?\s, attr]
- defp tag_for(type, attrs, children, encoder, padding, self_closing_tags) do
- encoder =
- case type do
- "script" -> @no_encoder
- "style" -> @no_encoder
- "title" -> @no_encoder
- _ -> encoder
- end
-
- children_content =
- case children do
- [] -> ""
- _ -> build_raw_html(children, "", encoder, pad_increase(padding), self_closing_tags)
- end
-
- [
- tag_with_attrs(type, attrs, children, padding, encoder, self_closing_tags),
- line_ending(padding),
- children_content,
- close_end_tag(type, children, padding, self_closing_tags)
- ]
- end
-
defp use_default_encoder? do
Application.get_env(:floki, :encode_raw_html, true)
end