This repository has been archived on 2023-08-07. You can view files and clone it, but cannot push or open issues or pull requests.
temple/lib/temple/converter.ex

104 lines
1.8 KiB
Elixir

defmodule Temple.Converter do
@moduledoc false
@boolean_attributes ~w[
allowfullscreen
async
autofocus
autoplay
checked
controls
default
defer
disabled
formnovalidate
ismap
itemscope
loop
multiple
muted
nomodule
novalidate
open
playsinline
readonly
required
reversed
selected
truespeed
]
def convert(html) do
html
|> Floki.parse_fragment!()
|> to_temple()
|> :erlang.iolist_to_binary()
|> Code.format_string!()
|> :erlang.iolist_to_binary()
end
def to_temple([]) do
[]
end
def to_temple([{tag, attrs, children} | rest]) do
[
to_string(tag),
" ",
to_temple_attrs(attrs),
" do\n",
to_temple(children),
"end\n"
] ++ to_temple(rest)
end
def to_temple([{:comment, comment} | rest]) do
[
comment
|> String.split("\n")
|> Enum.map_join("\n", fn line ->
if String.trim(line) != "" do
"# #{line}"
else
""
end
end),
"\n"
] ++ to_temple(rest)
end
def to_temple([text | rest]) when is_binary(text) do
[
text
|> String.split("\n")
|> Enum.map_join("\n", fn line ->
if String.trim(line) != "" do
escaped = String.replace(line, ~s|"|, ~s|\\"|)
~s|"#{String.trim(escaped)}"|
else
""
end
end),
"\n"
] ++ to_temple(rest)
end
defp to_temple_attrs([]) do
""
end
defp to_temple_attrs(attrs) do
Enum.map_join(attrs, ", ", fn
{attr, _value} when attr in @boolean_attributes ->
to_attr_name(attr) <> ": true"
{attr, value} ->
~s|#{to_attr_name(attr)}: "#{value}"|
end)
end
defp to_attr_name(name) do
String.replace(name, "-", "_")
end
end