defmodule Outlook.InternalTree.Html do alias Outlook.InternalTree.InternalNode alias Outlook.InternalTree.TranslationUnit @desirable_atts %{"a" => [:href], "img" => [:src]} @void_elements ~w(img br hr) def strip_attributes([%InternalNode{type: :element} = node | rest]) do d_atts = Map.get(@desirable_atts, node.name, []) atts = Map.reject(node.attributes, fn {k,_} -> k not in d_atts end) [ %{node | attributes: atts, content: strip_attributes(node.content) } | strip_attributes(rest) ] end def strip_attributes([node | rest]) do [ node | strip_attributes(rest)] end def strip_attributes([]), do: [] def to_html([%{type: :element} = node | rest]) when node.name in @void_elements do attr_string = Enum.map_join(node.attributes, "", fn {k,v} -> " #{k}=\"#{v}\"" end) "<#{node.name}#{attr_string}>" <> to_html(rest) end def to_html([%{type: :element} = node | rest]) do attr_string = Enum.map_join(node.attributes, "", fn {k,v} -> " #{k}=\"#{v}\"" end) "<#{node.name}#{attr_string}>" <> to_html(node.content) <> "" <> to_html(rest) end def to_html([%{type: :text} = node | rest]) do node.content <> to_html(rest) end def to_html([%{type: :comment} = node | rest]) do "" <> to_html(rest) end def to_html([%TranslationUnit{} = tunit | rest]) do ~s(#{tunit.content}) <> to_html(rest) end def to_html([]), do: "" def render_doc(tree) do OutlookWeb.HtmlDocComponent.render_doc(%{tree: tree}) |> Phoenix.HTML.Safe.to_iodata() |> IO.iodata_to_binary() end end