Packages
floki
0.20.4
0.38.4
0.38.3
0.38.2
0.38.1
0.38.0
0.37.1
0.37.0
0.36.3
0.36.2
0.36.1
0.36.0
0.35.4
0.35.3
0.35.2
0.35.1
0.35.0
0.34.3
0.34.2
0.34.1
0.34.0
0.33.1
0.33.0
0.32.1
0.32.0
0.31.0
0.30.1
0.30.0
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.1
0.23.0
0.22.0
0.21.0
0.20.4
0.20.3
0.20.2
0.20.1
0.20.0
0.19.3
0.19.2
0.19.1
0.19.0
0.18.1
0.18.0
0.17.2
0.17.1
0.17.0
0.16.0
0.15.0
0.14.0
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.0
0.10.1
0.10.0
0.9.0
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.0
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.1
0.1.0
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
Floki is a simple HTML parser that enables search for nodes using CSS selectors.
Current section
Files
Jump to
Current section
Files
lib/floki/raw_html.ex
defmodule Floki.RawHTML do
@moduledoc false
@self_closing_tags [
"area",
"base",
"br",
"col",
"command",
"embed",
"hr",
"img",
"input",
"keygen",
"link",
"meta",
"param",
"source",
"track",
"wbr"
]
@encoder &HtmlEntities.encode/1
def raw_html(html_tree, options) do
encoder =
case Keyword.fetch(options, :encode) do
{:ok, true} -> @encoder
{:ok, false} -> & &1
:error -> default_encoder()
end
build_raw_html(html_tree, "", encoder)
end
defp build_raw_html([], html, _encoder), do: html
defp build_raw_html(string, _html, encoder) when is_binary(string), do: encoder.(string)
defp build_raw_html(tuple, html, encoder) when is_tuple(tuple),
do: build_raw_html([tuple], html, encoder)
defp build_raw_html([string | tail], html, encoder) when is_binary(string) do
build_raw_html(tail, html <> encoder.(string), encoder)
end
defp build_raw_html([{:comment, comment} | tail], html, encoder),
do: build_raw_html(tail, html <> "<!--#{comment}-->", encoder)
defp build_raw_html([{:pi, "xml", attrs} | tail], html, encoder) do
build_raw_html(tail, html <> "<?xml " <> tag_attrs(attrs) <> "?>", encoder)
end
defp build_raw_html([{:doctype, type, public, system} | tail], html, encoder) do
attr =
case {public, system} do
{"", ""} -> ""
{"", system} -> " SYSTEM \"#{system}\""
{public, system} -> " PUBLIC \"#{public}\" \"#{system}\""
end
build_raw_html(tail, html <> "<!DOCTYPE #{type}#{attr}>", encoder)
end
defp build_raw_html([{type, attrs, children} | tail], html, encoder) do
build_raw_html(tail, html <> tag_for(type, attrs, children, encoder), encoder)
end
defp tag_attrs(attr_list) do
attr_list
|> Enum.reduce("", &build_attrs/2)
|> String.trim()
end
defp tag_with_attrs(type, [], children), do: "<#{type}" <> close_open_tag(type, children)
defp tag_with_attrs(type, attrs, children) do
"<#{type} #{tag_attrs(attrs)}" <> close_open_tag(type, children)
end
defp close_open_tag(type, []) when type in @self_closing_tags, do: "/>"
defp close_open_tag(_type, _), do: ">"
defp close_end_tag(type, []) when type in @self_closing_tags, do: ""
defp close_end_tag(type, _), do: "</#{type}>"
defp build_attrs({attr, iodata}, attrs) when is_list(iodata) do
build_attrs({attr, IO.iodata_to_binary(iodata)}, attrs)
end
defp build_attrs({attr, <<value::binary>>}, attrs) do
if String.contains?(value, "\"") do
~s(#{attrs} #{attr}='#{value}')
else
~s(#{attrs} #{attr}="#{value}")
end
end
defp build_attrs(<<attr::binary>>, attrs), do: "#{attrs} #{attr}"
defp tag_for(type, attrs, children, encoder) do
encoder =
case type do
"script" -> & &1
"style" -> & &1
_ -> encoder
end
tag_with_attrs(type, attrs, children) <>
build_raw_html(children, "", encoder) <> close_end_tag(type, children)
end
defp default_encoder do
if Application.get_env(:floki, :encode_raw_html, true) do
@encoder
else
& &1
end
end
end