Svg module (#25)
* Temple.Svg - scopes update_mdn_task to the temple namespace - introduces new temple.convert mix task to convert plain HTML and SVG to Temple syntax * Rename Temple.Tags to Temple.Html * Remove hackney I'm not sure why it was even in there ¯\_(ツ)_/¯ * Update floki * Document temple.convert in README
This commit is contained in:
parent
50c3bd93eb
commit
5acd6fc079
20 changed files with 515 additions and 94 deletions
|
@ -18,6 +18,15 @@ locals_without_parens = ~w[
|
||||||
area br col embed hr img input keygen param source track wbr
|
area br col embed hr img input keygen param source track wbr
|
||||||
text partial
|
text partial
|
||||||
|
|
||||||
|
animate animateMotion animateTransform circle clipPath
|
||||||
|
color-profile defs desc discard ellipse feBlend
|
||||||
|
feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feDropShadow
|
||||||
|
feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset
|
||||||
|
fePointLight feSpecularLighting feSpotLight feTile feTurbulence filter foreignObject g hatch hatchpath image line linearGradient
|
||||||
|
marker mask mesh meshgradient meshpatch meshrow metadata mpath path pattern polygon
|
||||||
|
polyline radialGradient rect set solidcolor stop svg switch symbol text_
|
||||||
|
textPath tspan unknown use view
|
||||||
|
|
||||||
form_for inputs_for
|
form_for inputs_for
|
||||||
checkbox color_input checkbox color_input date_input date_select datetime_local_input
|
checkbox color_input checkbox color_input date_input date_select datetime_local_input
|
||||||
datetime_select email_input file_input hidden_input number_input password_input range_input
|
datetime_select email_input file_input hidden_input number_input password_input range_input
|
||||||
|
|
|
@ -2,6 +2,14 @@
|
||||||
|
|
||||||
## Master
|
## Master
|
||||||
|
|
||||||
|
- `Temple.Svg` module
|
||||||
|
- `mix temple.convert` Mix task
|
||||||
|
- (dev) rename `mix update_mdn_docs` to `mix temple.update_mdn_docs` and don't ship it to hex
|
||||||
|
|
||||||
|
### Breaking
|
||||||
|
|
||||||
|
- Rename Temple.Tags to Temple.Html
|
||||||
|
|
||||||
## v0.3.1
|
## v0.3.1
|
||||||
|
|
||||||
- `Temple.Form.phx_label`, `Temple.Form.submit`, `Temple.Link.phx_button`, `Temple.Link.phx_link` now correctly parse blocks. Before this, they would escape anything passed to the block instead of accepting it as raw HTML.
|
- `Temple.Form.phx_label`, `Temple.Form.submit`, `Temple.Link.phx_button`, `Temple.Link.phx_link` now correctly parse blocks. Before this, they would escape anything passed to the block instead of accepting it as raw HTML.
|
||||||
|
|
10
README.md
10
README.md
|
@ -22,7 +22,7 @@ end
|
||||||
|
|
||||||
Using Temple is a as simple as using the DSL inside of an `temple/1` block. This returns a safe result of the form `{:safe, html_string}`.
|
Using Temple is a as simple as using the DSL inside of an `temple/1` block. This returns a safe result of the form `{:safe, html_string}`.
|
||||||
|
|
||||||
See the [documentation](https://hexdocs.pm/temple/Temple.Tags.html) for more details.
|
See the [documentation](https://hexdocs.pm/temple/Temple.Html.html) for more details.
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
use Temple
|
use Temple
|
||||||
|
@ -153,6 +153,14 @@ html lang: "en" do
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Tasks
|
||||||
|
|
||||||
|
#### temple.convert
|
||||||
|
|
||||||
|
This task can be used to convert plain HTML and SVG into Temple syntax. Input is taken from stdin or from a file and the output is sent to stdout.
|
||||||
|
|
||||||
|
`cat index.html | mix temple.convert > index.html.exs`
|
||||||
|
|
||||||
### Formatter
|
### Formatter
|
||||||
|
|
||||||
To include Temple's formatter configuration, add `:temple` to your `.formatter.exs`.
|
To include Temple's formatter configuration, add `:temple` to your `.formatter.exs`.
|
||||||
|
|
22
lib/mix/tasks/temple.convert.ex
Normal file
22
lib/mix/tasks/temple.convert.ex
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
defmodule Mix.Tasks.Temple.Convert do
|
||||||
|
use Mix.Task
|
||||||
|
@shortdoc "Converts HTML to Temple syntax"
|
||||||
|
@moduledoc """
|
||||||
|
Converts HTML to Temple syntax
|
||||||
|
|
||||||
|
Takes HTML from a file or from stdin and outputs temple syntax to stdout.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def run(args) do
|
||||||
|
html =
|
||||||
|
if Enum.count(args) > 0 do
|
||||||
|
args |> List.first() |> File.read!()
|
||||||
|
else
|
||||||
|
IO.read(:stdio, :all)
|
||||||
|
end
|
||||||
|
|
||||||
|
{:ok, result} = Temple.HtmlToTemple.parse(html)
|
||||||
|
|
||||||
|
IO.write(result)
|
||||||
|
end
|
||||||
|
end
|
48
lib/mix/tasks/temple.update_mdn_docs.ex
Normal file
48
lib/mix/tasks/temple.update_mdn_docs.ex
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
defmodule Mix.Tasks.Temple.UpdateMdnDocs do
|
||||||
|
use Mix.Task
|
||||||
|
|
||||||
|
@html_base_url "https://developer.mozilla.org/en-US/docs/Web/HTML/Element/"
|
||||||
|
@svg_base_url "https://developer.mozilla.org/en-US/docs/Web/SVG/Element/"
|
||||||
|
@params "?summary&raw"
|
||||||
|
|
||||||
|
@shortdoc "Update the MDN documentation"
|
||||||
|
def run(_) do
|
||||||
|
IO.puts("Downloading HTML documentation")
|
||||||
|
|
||||||
|
(Temple.Html.nonvoid_elements() ++ Temple.Html.void_elements() ++ ["html"])
|
||||||
|
|> Enum.map(
|
||||||
|
&to_doc(to_string(&1), "./tmp/docs/html/", fn el -> base_url(:html, html_page(el)) end)
|
||||||
|
)
|
||||||
|
|> Enum.each(&Task.await/1)
|
||||||
|
|
||||||
|
IO.puts("Downloading SVG documentation")
|
||||||
|
|
||||||
|
Temple.Svg.elements()
|
||||||
|
|> Enum.map(&Temple.Utils.to_valid_tag(&1))
|
||||||
|
|> Enum.map(&to_doc(&1, "./tmp/docs/svg/", fn el -> base_url(:svg, el) end))
|
||||||
|
|> Enum.each(&Task.await/1)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp to_doc(el, dir_path, url_getter) do
|
||||||
|
Task.async(fn ->
|
||||||
|
url = url_getter.(el)
|
||||||
|
|
||||||
|
{doc, 0} = System.cmd("curl", ["--silent", url])
|
||||||
|
|
||||||
|
File.mkdir_p!(dir_path)
|
||||||
|
|
||||||
|
doc = HtmlSanitizeEx.strip_tags(doc)
|
||||||
|
|
||||||
|
File.write!(dir_path <> el <> ".txt", doc)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp html_page(el) when el in ["h1", "h2", "h3", "h4", "h5", "h6"] do
|
||||||
|
"Heading_Elements"
|
||||||
|
end
|
||||||
|
|
||||||
|
defp html_page(el), do: el
|
||||||
|
|
||||||
|
defp base_url(:html, page), do: @html_base_url <> page <> @params
|
||||||
|
defp base_url(:svg, page), do: @svg_base_url <> page <> @params
|
||||||
|
end
|
|
@ -1,34 +0,0 @@
|
||||||
defmodule Mix.Tasks.UpdateMdnDocs do
|
|
||||||
use Mix.Task
|
|
||||||
|
|
||||||
@baseurl "https://developer.mozilla.org/en-US/docs/Web/HTML/Element/"
|
|
||||||
@params "?summary&raw"
|
|
||||||
|
|
||||||
@shortdoc "Update the MDN documentation"
|
|
||||||
def run(_) do
|
|
||||||
IO.puts("Downloading MDN documentation")
|
|
||||||
|
|
||||||
(Temple.Tags.nonvoid_elements() ++ Temple.Tags.void_elements() ++ ["html"])
|
|
||||||
|> Enum.map(fn el ->
|
|
||||||
Task.async(fn ->
|
|
||||||
el = to_string(el)
|
|
||||||
|
|
||||||
page =
|
|
||||||
if Enum.any?(["h1", "h2", "h3", "h4", "h5", "h6"], &(&1 == el)) do
|
|
||||||
"Heading_Elements"
|
|
||||||
else
|
|
||||||
el
|
|
||||||
end
|
|
||||||
|
|
||||||
{doc, 0} = System.cmd("curl", ["--silent", @baseurl <> page <> @params])
|
|
||||||
File.mkdir_p!("./tmp/docs/")
|
|
||||||
|
|
||||||
path = "./tmp/docs/" <> el <> ".txt"
|
|
||||||
doc = HtmlSanitizeEx.strip_tags(doc)
|
|
||||||
|
|
||||||
File.write!(path, doc)
|
|
||||||
end)
|
|
||||||
end)
|
|
||||||
|> Enum.each(&Task.await/1)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -2,9 +2,6 @@ defmodule Temple do
|
||||||
defmacro __using__(_) do
|
defmacro __using__(_) do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
import Temple
|
import Temple
|
||||||
import Temple.Tags
|
|
||||||
import Temple.Form
|
|
||||||
import Temple.Link
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -33,14 +30,18 @@ defmodule Temple do
|
||||||
"""
|
"""
|
||||||
defmacro temple([do: block] = _block) do
|
defmacro temple([do: block] = _block) do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
import Kernel, except: [div: 2]
|
import Kernel, except: [div: 2, use: 1, use: 2]
|
||||||
|
import Temple.Html
|
||||||
|
import Temple.Svg
|
||||||
|
import Temple.Form
|
||||||
|
import Temple.Link
|
||||||
|
|
||||||
with {:ok, var!(buff, Temple.Tags)} <- Temple.Utils.start_buffer([]) do
|
with {:ok, var!(buff, Temple.Html)} <- Temple.Utils.start_buffer([]) do
|
||||||
unquote(block)
|
unquote(block)
|
||||||
|
|
||||||
markup = Temple.Utils.get_buffer(var!(buff, Temple.Tags))
|
markup = Temple.Utils.get_buffer(var!(buff, Temple.Html))
|
||||||
|
|
||||||
:ok = Temple.Utils.stop_buffer(var!(buff, Temple.Tags))
|
:ok = Temple.Utils.stop_buffer(var!(buff, Temple.Html))
|
||||||
|
|
||||||
Temple.Utils.join_and_escape(markup)
|
Temple.Utils.join_and_escape(markup)
|
||||||
end
|
end
|
||||||
|
@ -63,7 +64,7 @@ defmodule Temple do
|
||||||
defmacro text(text) do
|
defmacro text(text) do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
Temple.Utils.put_buffer(
|
Temple.Utils.put_buffer(
|
||||||
var!(buff, Temple.Tags),
|
var!(buff, Temple.Html),
|
||||||
unquote(text) |> Temple.Utils.escape_content()
|
unquote(text) |> Temple.Utils.escape_content()
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -98,7 +99,7 @@ defmodule Temple do
|
||||||
defmacro partial(partial) do
|
defmacro partial(partial) do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
Temple.Utils.put_buffer(
|
Temple.Utils.put_buffer(
|
||||||
var!(buff, Temple.Tags),
|
var!(buff, Temple.Html),
|
||||||
unquote(partial) |> Temple.Utils.from_safe()
|
unquote(partial) |> Temple.Utils.from_safe()
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
defmodule Temple.Elements do
|
defmodule Temple.Elements do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
This module contains the primitives used to generate the macros in the `Temple.Tags` module.
|
This module contains the primitives used to generate the macros in the `Temple.Html` and `Temple.Svg` modules.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Defines an element.
|
Defines an element.
|
||||||
|
|
||||||
*Note*: Underscores are converted to hypens.
|
*Note*: Underscores are converted to dashes.
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
defmodule MyElements do
|
defmodule MyElements do
|
||||||
|
@ -26,6 +26,7 @@ defmodule Temple.Elements do
|
||||||
Temple.Elements.nonvoid_element(unquote(name))
|
Temple.Elements.nonvoid_element(unquote(name))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc false
|
||||||
defmacro unquote(name)(attrs_or_content_or_block)
|
defmacro unquote(name)(attrs_or_content_or_block)
|
||||||
|
|
||||||
defmacro unquote(name)([{:do, _inner}] = block) do
|
defmacro unquote(name)([{:do, _inner}] = block) do
|
||||||
|
@ -36,6 +37,7 @@ defmodule Temple.Elements do
|
||||||
Temple.Elements.nonvoid_element(unquote(name), attrs_or_content)
|
Temple.Elements.nonvoid_element(unquote(name), attrs_or_content)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc false
|
||||||
defmacro unquote(name)(attrs_or_content, block_or_attrs)
|
defmacro unquote(name)(attrs_or_content, block_or_attrs)
|
||||||
|
|
||||||
defmacro unquote(name)(attrs, [{:do, _inner}] = block) do
|
defmacro unquote(name)(attrs, [{:do, _inner}] = block) do
|
||||||
|
@ -59,8 +61,8 @@ defmodule Temple.Elements do
|
||||||
@doc false
|
@doc false
|
||||||
def nonvoid_element(el) do
|
def nonvoid_element(el) do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
Temple.Utils.put_open_tag(var!(buff, Temple.Tags), unquote(el), [])
|
Temple.Utils.put_open_tag(var!(buff, Temple.Html), unquote(el), [])
|
||||||
Temple.Utils.put_close_tag(var!(buff, Temple.Tags), unquote(el))
|
Temple.Utils.put_close_tag(var!(buff, Temple.Html), unquote(el))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -69,16 +71,16 @@ defmodule Temple.Elements do
|
||||||
|
|
||||||
def nonvoid_element(el, [{:do, inner}]) do
|
def nonvoid_element(el, [{:do, inner}]) do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
Temple.Utils.put_open_tag(var!(buff, Temple.Tags), unquote(el), [])
|
Temple.Utils.put_open_tag(var!(buff, Temple.Html), unquote(el), [])
|
||||||
_ = unquote(inner)
|
_ = unquote(inner)
|
||||||
Temple.Utils.put_close_tag(var!(buff, Temple.Tags), unquote(el))
|
Temple.Utils.put_close_tag(var!(buff, Temple.Html), unquote(el))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def nonvoid_element(el, attrs_or_content) do
|
def nonvoid_element(el, attrs_or_content) do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
Temple.Utils.put_open_tag(var!(buff, Temple.Tags), unquote(el), unquote(attrs_or_content))
|
Temple.Utils.put_open_tag(var!(buff, Temple.Html), unquote(el), unquote(attrs_or_content))
|
||||||
Temple.Utils.put_close_tag(var!(buff, Temple.Tags), unquote(el))
|
Temple.Utils.put_close_tag(var!(buff, Temple.Html), unquote(el))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -87,24 +89,24 @@ defmodule Temple.Elements do
|
||||||
|
|
||||||
def nonvoid_element(el, attrs, [{:do, inner}] = _block) do
|
def nonvoid_element(el, attrs, [{:do, inner}] = _block) do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
Temple.Utils.put_open_tag(var!(buff, Temple.Tags), unquote_splicing([el, attrs]))
|
Temple.Utils.put_open_tag(var!(buff, Temple.Html), unquote_splicing([el, attrs]))
|
||||||
_ = unquote(inner)
|
_ = unquote(inner)
|
||||||
Temple.Utils.put_close_tag(var!(buff, Temple.Tags), unquote(el))
|
Temple.Utils.put_close_tag(var!(buff, Temple.Html), unquote(el))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def nonvoid_element(el, content, attrs) do
|
def nonvoid_element(el, content, attrs) do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
Temple.Utils.put_open_tag(var!(buff, Temple.Tags), unquote_splicing([el, attrs]))
|
Temple.Utils.put_open_tag(var!(buff, Temple.Html), unquote_splicing([el, attrs]))
|
||||||
text unquote(content)
|
text unquote(content)
|
||||||
Temple.Utils.put_close_tag(var!(buff, Temple.Tags), unquote(el))
|
Temple.Utils.put_close_tag(var!(buff, Temple.Html), unquote(el))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc false
|
@doc false
|
||||||
def void_element(el, attrs \\ []) do
|
def void_element(el, attrs \\ []) do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
Temple.Utils.put_void_tag(var!(buff, Temple.Tags), unquote_splicing([el, attrs]))
|
Temple.Utils.put_void_tag(var!(buff, Temple.Html), unquote_splicing([el, attrs]))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -45,9 +45,9 @@ defmodule Temple.Form do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
var!(form) = HTML.Form.form_for(unquote_splicing([form_data, action, opts]))
|
var!(form) = HTML.Form.form_for(unquote_splicing([form_data, action, opts]))
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), var!(form) |> HTML.Safe.to_iodata())
|
Utils.put_buffer(var!(buff, Temple.Html), var!(form) |> HTML.Safe.to_iodata())
|
||||||
_ = unquote(block)
|
_ = unquote(block)
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), "</form>")
|
Utils.put_buffer(var!(buff, Temple.Html), "</form>")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ defmodule Temple.Form do
|
||||||
{:safe, input} =
|
{:safe, input} =
|
||||||
apply(Phoenix.HTML.Form, unquote(helper), [unquote_splicing([form, field, opts])])
|
apply(Phoenix.HTML.Form, unquote(helper), [unquote_splicing([form, field, opts])])
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), input)
|
Utils.put_buffer(var!(buff, Temple.Html), input)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -97,7 +97,7 @@ defmodule Temple.Form do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
{:safe, input} = Phoenix.HTML.Form.textarea(unquote_splicing([form, field, opts]))
|
{:safe, input} = Phoenix.HTML.Form.textarea(unquote_splicing([form, field, opts]))
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), input)
|
Utils.put_buffer(var!(buff, Temple.Html), input)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ defmodule Temple.Form do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
{:safe, input} = Phoenix.HTML.Form.reset(unquote_splicing([value, opts]))
|
{:safe, input} = Phoenix.HTML.Form.reset(unquote_splicing([value, opts]))
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), input)
|
Utils.put_buffer(var!(buff, Temple.Html), input)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ defmodule Temple.Form do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
{:safe, input} = Phoenix.HTML.Form.submit(do: temple(do: unquote(block)))
|
{:safe, input} = Phoenix.HTML.Form.submit(do: temple(do: unquote(block)))
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), input)
|
Utils.put_buffer(var!(buff, Temple.Html), input)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ defmodule Temple.Form do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
{:safe, input} = Phoenix.HTML.Form.submit(unquote(value))
|
{:safe, input} = Phoenix.HTML.Form.submit(unquote(value))
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), input)
|
Utils.put_buffer(var!(buff, Temple.Html), input)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ defmodule Temple.Form do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
{:safe, input} = Phoenix.HTML.Form.submit(unquote(opts), do: temple(do: unquote(block)))
|
{:safe, input} = Phoenix.HTML.Form.submit(unquote(opts), do: temple(do: unquote(block)))
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), input)
|
Utils.put_buffer(var!(buff, Temple.Html), input)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ defmodule Temple.Form do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
{:safe, input} = Phoenix.HTML.Form.submit(unquote_splicing([value, opts]))
|
{:safe, input} = Phoenix.HTML.Form.submit(unquote_splicing([value, opts]))
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), input)
|
Utils.put_buffer(var!(buff, Temple.Html), input)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ defmodule Temple.Form do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
{:safe, input} = Phoenix.HTML.Form.label(unquote_splicing([form, field]))
|
{:safe, input} = Phoenix.HTML.Form.label(unquote_splicing([form, field]))
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), input)
|
Utils.put_buffer(var!(buff, Temple.Html), input)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ defmodule Temple.Form do
|
||||||
{:safe, input} =
|
{:safe, input} =
|
||||||
Phoenix.HTML.Form.label(unquote_splicing([form, field]), do: temple(do: unquote(block)))
|
Phoenix.HTML.Form.label(unquote_splicing([form, field]), do: temple(do: unquote(block)))
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), input)
|
Utils.put_buffer(var!(buff, Temple.Html), input)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ defmodule Temple.Form do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
{:safe, input} = Phoenix.HTML.Form.label(unquote_splicing([form, field, text_or_opts]))
|
{:safe, input} = Phoenix.HTML.Form.label(unquote_splicing([form, field, text_or_opts]))
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), input)
|
Utils.put_buffer(var!(buff, Temple.Html), input)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ defmodule Temple.Form do
|
||||||
do: temple(do: unquote(block))
|
do: temple(do: unquote(block))
|
||||||
)
|
)
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), input)
|
Utils.put_buffer(var!(buff, Temple.Html), input)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ defmodule Temple.Form do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
{:safe, input} = Phoenix.HTML.Form.label(unquote_splicing([form, field, text, opts]))
|
{:safe, input} = Phoenix.HTML.Form.label(unquote_splicing([form, field, text, opts]))
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), input)
|
Utils.put_buffer(var!(buff, Temple.Html), input)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ defmodule Temple.Form do
|
||||||
{:safe, input} =
|
{:safe, input} =
|
||||||
Phoenix.HTML.Form.radio_button(unquote_splicing([form, field, value, attrs]))
|
Phoenix.HTML.Form.radio_button(unquote_splicing([form, field, value, attrs]))
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), input)
|
Utils.put_buffer(var!(buff, Temple.Html), input)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ defmodule Temple.Form do
|
||||||
{:safe, input} =
|
{:safe, input} =
|
||||||
Phoenix.HTML.Form.multiple_select(unquote_splicing([form, field, options, attrs]))
|
Phoenix.HTML.Form.multiple_select(unquote_splicing([form, field, options, attrs]))
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), input)
|
Utils.put_buffer(var!(buff, Temple.Html), input)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ defmodule Temple.Form do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
{:safe, input} = Phoenix.HTML.Form.select(unquote_splicing([form, field, options, attrs]))
|
{:safe, input} = Phoenix.HTML.Form.select(unquote_splicing([form, field, options, attrs]))
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), input)
|
Utils.put_buffer(var!(buff, Temple.Html), input)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -293,7 +293,7 @@ defmodule Temple.Form do
|
||||||
|
|
||||||
hidden_input
|
hidden_input
|
||||||
end)
|
end)
|
||||||
|> Enum.each(&Utils.put_buffer(var!(buff, Temple.Tags), &1))
|
|> Enum.each(&Utils.put_buffer(var!(buff, Temple.Html), &1))
|
||||||
|
|
||||||
var!(inner_form) = form
|
var!(inner_form) = form
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
defmodule Temple.Tags do
|
defmodule Temple.Html do
|
||||||
require Temple.Elements
|
require Temple.Elements
|
||||||
|
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
The `Temple.Tags` module defines macros for all HTML5 compliant elements.
|
The `Temple.Html` module defines macros for all HTML5 compliant elements.
|
||||||
|
|
||||||
`Temple.Tags` macros must be called inside of a `Temple.temple/1` block.
|
`Temple.Html` macros must be called inside of a `Temple.temple/1` block.
|
||||||
|
|
||||||
|
*Note*: Only the lowest arity macros are documented. Void elements are defined as a 1-arity macro and non-void elements are defined as 0, 1, and 2-arity macros.
|
||||||
|
|
||||||
## Attributes
|
## Attributes
|
||||||
|
|
||||||
Tags accept a keyword list or a map of attributes to be emitted into the element's opening tag. Multi-word attribute keys written in snake_case (`data_url`) will be transformed into kebab-case (`data-url`).
|
Html accept a keyword list or a map of attributes to be emitted into the element's opening tag. Multi-word attribute keys written in snake_case (`data_url`) will be transformed into kebab-case (`data-url`).
|
||||||
|
|
||||||
## Children
|
## Children
|
||||||
|
|
||||||
|
@ -88,20 +90,20 @@ defmodule Temple.Tags do
|
||||||
def void_elements, do: @void_elements
|
def void_elements, do: @void_elements
|
||||||
|
|
||||||
for el <- @nonvoid_elements do
|
for el <- @nonvoid_elements do
|
||||||
@doc if File.exists?("./tmp/docs/#{el}.txt"), do: File.read!("./tmp/docs/#{el}.txt")
|
@doc if File.exists?("./tmp/docs/html/#{el}.txt"), do: File.read!("./tmp/docs/html/#{el}.txt")
|
||||||
Temple.Elements.defelement(unquote(el), :nonvoid)
|
Temple.Elements.defelement(unquote(el), :nonvoid)
|
||||||
end
|
end
|
||||||
|
|
||||||
for el <- @void_elements do
|
for el <- @void_elements do
|
||||||
@doc if File.exists?("./tmp/docs/#{el}.txt"), do: File.read!("./tmp/docs/#{el}.txt")
|
@doc if File.exists?("./tmp/docs/html/#{el}.txt"), do: File.read!("./tmp/docs/html/#{el}.txt")
|
||||||
Temple.Elements.defelement(unquote(el), :void)
|
Temple.Elements.defelement(unquote(el), :void)
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc if File.exists?("./tmp/docs/html.txt"), do: File.read!("./tmp/docs/html.txt")
|
@doc if File.exists?("./tmp/docs/html/html.txt"), do: File.read!("./tmp/docs/html/html.txt")
|
||||||
defmacro html(attrs \\ [], [{:do, _inner}] = block) do
|
defmacro html(attrs \\ [], [{:do, _inner}] = block) do
|
||||||
doc_type =
|
doc_type =
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
Temple.Utils.put_buffer(var!(buff, Temple.Tags), "<!DOCTYPE html>")
|
Temple.Utils.put_buffer(var!(buff, Temple.Html), "<!DOCTYPE html>")
|
||||||
end
|
end
|
||||||
|
|
||||||
[doc_type, Temple.Elements.nonvoid_element(:html, attrs, block)]
|
[doc_type, Temple.Elements.nonvoid_element(:html, attrs, block)]
|
74
lib/temple/html_to_temple.ex
Normal file
74
lib/temple/html_to_temple.ex
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
defmodule Temple.HtmlToTemple do
|
||||||
|
@moduledoc false
|
||||||
|
|
||||||
|
@tags Temple.Html.void_elements() ++
|
||||||
|
Temple.Html.nonvoid_elements() ++ Temple.Svg.elements() ++ [:html]
|
||||||
|
|
||||||
|
def parse(doc) do
|
||||||
|
result =
|
||||||
|
doc
|
||||||
|
|> Floki.parse()
|
||||||
|
|> do_parse(0)
|
||||||
|
|
||||||
|
{:ok, result}
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_parse({tag, [], []}, indent) do
|
||||||
|
tag = tag |> find_tag
|
||||||
|
(Temple.Utils.kebab_to_snake(tag) <> "()\n") |> pad_indent(indent)
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_parse({tag, attrs, []}, indent) do
|
||||||
|
tag = tag |> find_tag
|
||||||
|
(Temple.Utils.kebab_to_snake(tag) <> build_attrs(attrs) <> "\n") |> pad_indent(indent)
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_parse({tag, attrs, [""]}, indent), do: do_parse({tag, attrs, []}, indent)
|
||||||
|
|
||||||
|
def do_parse({tag, attrs, children}, indent) do
|
||||||
|
tag = tag |> find_tag
|
||||||
|
|
||||||
|
head =
|
||||||
|
(Temple.Utils.kebab_to_snake(tag) <> build_attrs(attrs) <> " do\n")
|
||||||
|
|> pad_indent(indent)
|
||||||
|
|
||||||
|
parsed_childs =
|
||||||
|
for child <- children do
|
||||||
|
do_parse(child, indent + 1)
|
||||||
|
end
|
||||||
|
|> Enum.join("\n")
|
||||||
|
|
||||||
|
head <> parsed_childs <> pad_indent("end\n", indent)
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_parse(text, indent) when is_binary(text) do
|
||||||
|
(~s|text "| <> text <> ~s|"\n|) |> pad_indent(indent)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp build_attrs([]), do: ""
|
||||||
|
|
||||||
|
defp build_attrs(attrs) do
|
||||||
|
attrs =
|
||||||
|
for {key, value} <- attrs do
|
||||||
|
wrap_in_quotes(key) <> ~s|: "| <> value <> ~s|"|
|
||||||
|
end
|
||||||
|
|> Enum.join(", ")
|
||||||
|
|
||||||
|
" " <> attrs
|
||||||
|
end
|
||||||
|
|
||||||
|
defp wrap_in_quotes(key) do
|
||||||
|
if Regex.match?(~r/[^a-zA-Z_]/, key) do
|
||||||
|
~s|"| <> key <> ~s|"|
|
||||||
|
else
|
||||||
|
key
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp pad_indent(paddable, indent) do
|
||||||
|
String.pad_leading(paddable, 2 * indent + String.length(paddable))
|
||||||
|
end
|
||||||
|
|
||||||
|
defp find_tag(tag),
|
||||||
|
do: @tags |> Enum.find(fn x -> String.downcase(to_string(x)) == tag end)
|
||||||
|
end
|
|
@ -15,7 +15,7 @@ defmodule Temple.Link do
|
||||||
temple(do: unquote(block))
|
temple(do: unquote(block))
|
||||||
|> HTML.Link.link(unquote(opts))
|
|> HTML.Link.link(unquote(opts))
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), link)
|
Utils.put_buffer(var!(buff, Temple.Html), link)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ defmodule Temple.Link do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
{:safe, link} = HTML.Link.link(unquote_splicing([content, opts]))
|
{:safe, link} = HTML.Link.link(unquote_splicing([content, opts]))
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), link)
|
Utils.put_buffer(var!(buff, Temple.Html), link)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ defmodule Temple.Link do
|
||||||
temple(do: unquote(block))
|
temple(do: unquote(block))
|
||||||
|> HTML.Link.button(unquote(opts))
|
|> HTML.Link.button(unquote(opts))
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), link)
|
Utils.put_buffer(var!(buff, Temple.Html), link)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ defmodule Temple.Link do
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
{:safe, link} = HTML.Link.button(unquote_splicing([content, opts]))
|
{:safe, link} = HTML.Link.button(unquote_splicing([content, opts]))
|
||||||
|
|
||||||
Utils.put_buffer(var!(buff, Temple.Tags), link)
|
Utils.put_buffer(var!(buff, Temple.Html), link)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
29
lib/temple/svg.ex
Normal file
29
lib/temple/svg.ex
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
defmodule Temple.Svg do
|
||||||
|
require Temple.Elements
|
||||||
|
|
||||||
|
@moduledoc """
|
||||||
|
The `Temple.Svg` module defines macros for all SVG elements.
|
||||||
|
|
||||||
|
Usage is the same as `Temple.Html`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@elements ~w[
|
||||||
|
animate animateMotion animateTransform circle clipPath
|
||||||
|
color_profile defs desc discard ellipse feBlend
|
||||||
|
feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feDropShadow
|
||||||
|
feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset
|
||||||
|
fePointLight feSpecularLighting feSpotLight feTile feTurbulence filter foreignObject g hatch hatchpath image line linearGradient
|
||||||
|
marker mask metadata mpath path pattern polygon
|
||||||
|
polyline radialGradient rect set solidcolor stop svg switch symbol text_
|
||||||
|
textPath tspan use view
|
||||||
|
]a
|
||||||
|
|
||||||
|
@doc false
|
||||||
|
def elements(), do: @elements
|
||||||
|
|
||||||
|
for el <- @elements do
|
||||||
|
@doc if File.exists?("./tmp/docs/svg/#{Temple.Utils.to_valid_tag(el)}.txt"),
|
||||||
|
do: File.read!("./tmp/docs/svg/#{Temple.Utils.to_valid_tag(el)}.txt")
|
||||||
|
Temple.Elements.defelement(unquote(el), :nonvoid)
|
||||||
|
end
|
||||||
|
end
|
|
@ -74,7 +74,10 @@ defmodule Temple.Utils do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp snake_to_kebab(stringable),
|
defp snake_to_kebab(stringable),
|
||||||
do: stringable |> to_string() |> String.replace("_", "-")
|
do: stringable |> to_string() |> String.replace_trailing("_", "") |> String.replace("_", "-")
|
||||||
|
|
||||||
|
def kebab_to_snake(stringable),
|
||||||
|
do: stringable |> to_string() |> String.replace("-", "_")
|
||||||
|
|
||||||
def __quote__(outer) do
|
def __quote__(outer) do
|
||||||
quote [location: :keep], do: unquote(outer)
|
quote [location: :keep], do: unquote(outer)
|
||||||
|
@ -84,4 +87,10 @@ defmodule Temple.Utils do
|
||||||
block
|
block
|
||||||
|> Macro.prewalk(&Temple.Utils.insert_props(&1, props, inner))
|
|> Macro.prewalk(&Temple.Utils.insert_props(&1, props, inner))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def doc_path(:html, el), do: "./tmp/docs/html/#{el}.txt"
|
||||||
|
def doc_path(:svg, el), do: "./tmp/docs/svg/#{el}.txt"
|
||||||
|
|
||||||
|
def to_valid_tag(tag),
|
||||||
|
do: tag |> to_string |> String.replace_trailing("_", "") |> String.replace("_", "-")
|
||||||
end
|
end
|
||||||
|
|
6
mix.exs
6
mix.exs
|
@ -40,13 +40,14 @@ defmodule Temple.MixProject do
|
||||||
maintainers: ["Mitchell Hanberg"],
|
maintainers: ["Mitchell Hanberg"],
|
||||||
licenses: ["MIT"],
|
licenses: ["MIT"],
|
||||||
links: %{github: "https://github.com/mhanberg/temple"},
|
links: %{github: "https://github.com/mhanberg/temple"},
|
||||||
|
exclude_patterns: ["temple.update_mdn_docs.ex"],
|
||||||
files: ~w(lib priv CHANGELOG.md LICENSE mix.exs README.md .formatter.exs)
|
files: ~w(lib priv CHANGELOG.md LICENSE mix.exs README.md .formatter.exs)
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
defp aliases do
|
defp aliases do
|
||||||
[
|
[
|
||||||
docs: ["update_mdn_docs", "docs"]
|
docs: ["temple.update_mdn_docs", "docs"]
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -58,7 +59,8 @@ defmodule Temple.MixProject do
|
||||||
{:ex_doc, "~> 0.0", only: [:dev], runtime: false},
|
{:ex_doc, "~> 0.0", only: [:dev], runtime: false},
|
||||||
{:html_sanitize_ex, "~> 1.3", only: [:dev, :test], runtime: false},
|
{:html_sanitize_ex, "~> 1.3", only: [:dev, :test], runtime: false},
|
||||||
{:phoenix, "~> 1.4", optional: true},
|
{:phoenix, "~> 1.4", optional: true},
|
||||||
{:plug, "~> 1.8", optional: true}
|
{:plug, "~> 1.8", optional: true},
|
||||||
|
{:floki, "~> 0.23.0"}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
2
mix.lock
2
mix.lock
|
@ -3,6 +3,8 @@
|
||||||
"earmark": {:hex, :earmark, "1.3.5", "0db71c8290b5bc81cb0101a2a507a76dca659513984d683119ee722828b424f6", [:mix], [], "hexpm"},
|
"earmark": {:hex, :earmark, "1.3.5", "0db71c8290b5bc81cb0101a2a507a76dca659513984d683119ee722828b424f6", [:mix], [], "hexpm"},
|
||||||
"ecto": {:hex, :ecto, "3.2.0", "940e2598813f205223d60c78d66e514afe1db5167ed8075510a59e496619cfb5", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
|
"ecto": {:hex, :ecto, "3.2.0", "940e2598813f205223d60c78d66e514afe1db5167ed8075510a59e496619cfb5", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
"ex_doc": {:hex, :ex_doc, "0.21.2", "caca5bc28ed7b3bdc0b662f8afe2bee1eedb5c3cf7b322feeeb7c6ebbde089d6", [:mix], [{:earmark, "~> 1.3.3 or ~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
|
"ex_doc": {:hex, :ex_doc, "0.21.2", "caca5bc28ed7b3bdc0b662f8afe2bee1eedb5c3cf7b322feeeb7c6ebbde089d6", [:mix], [{:earmark, "~> 1.3.3 or ~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"floki": {:hex, :floki, "0.23.0", "956ab6dba828c96e732454809fb0bd8d43ce0979b75f34de6322e73d4c917829", [:mix], [{:html_entities, "~> 0.4.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"html_entities": {:hex, :html_entities, "0.4.0", "f2fee876858cf6aaa9db608820a3209e45a087c5177332799592142b50e89a6b", [:mix], [], "hexpm"},
|
||||||
"html_sanitize_ex": {:hex, :html_sanitize_ex, "1.3.0", "f005ad692b717691203f940c686208aa3d8ffd9dd4bb3699240096a51fa9564e", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"},
|
"html_sanitize_ex": {:hex, :html_sanitize_ex, "1.3.0", "f005ad692b717691203f940c686208aa3d8ffd9dd4bb3699240096a51fa9564e", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
|
"makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
|
"makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
|
89
test/mix/tasks/html_to_temple_test.exs
Normal file
89
test/mix/tasks/html_to_temple_test.exs
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
defmodule Mix.Tasks.HtmlToTempleTest do
|
||||||
|
use ExUnit.Case, async: true
|
||||||
|
|
||||||
|
test "converts html to temple syntax" do
|
||||||
|
html = """
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta>
|
||||||
|
<script></script>
|
||||||
|
<link>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header class="header" data-action="do a thing">
|
||||||
|
<nav role="navigation">
|
||||||
|
<ul>
|
||||||
|
<li><a href="/home">Home</a></li>
|
||||||
|
<li><a href="/about">About</a></li>
|
||||||
|
<li><a href="/profile">Profile</a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main role="main">
|
||||||
|
<svg>
|
||||||
|
<path d="alksdjfalksdjfslkadfj"/>
|
||||||
|
<linearGradient>
|
||||||
|
<stop></stop>
|
||||||
|
</linearGradient
|
||||||
|
</svg>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer></footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
|
||||||
|
{:ok, result} = Temple.HtmlToTemple.parse(html)
|
||||||
|
|
||||||
|
assert result === """
|
||||||
|
html lang: "en" do
|
||||||
|
head do
|
||||||
|
meta()
|
||||||
|
|
||||||
|
script()
|
||||||
|
|
||||||
|
link()
|
||||||
|
end
|
||||||
|
|
||||||
|
body do
|
||||||
|
header class: "header", "data-action": "do a thing" do
|
||||||
|
nav role: "navigation" do
|
||||||
|
ul do
|
||||||
|
li do
|
||||||
|
a href: "/home" do
|
||||||
|
text "Home"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
li do
|
||||||
|
a href: "/about" do
|
||||||
|
text "About"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
li do
|
||||||
|
a href: "/profile" do
|
||||||
|
text "Profile"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
main role: "main" do
|
||||||
|
svg do
|
||||||
|
path d: "alksdjfalksdjfslkadfj"
|
||||||
|
|
||||||
|
linearGradient do
|
||||||
|
stop()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
footer()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,7 +2,7 @@ defmodule Temple.ElementsTest do
|
||||||
use ExUnit.Case, async: true
|
use ExUnit.Case, async: true
|
||||||
import Temple.Elements, only: [defelement: 2]
|
import Temple.Elements, only: [defelement: 2]
|
||||||
import Temple, only: [temple: 1, text: 1]
|
import Temple, only: [temple: 1, text: 1]
|
||||||
import Temple.Tags, only: [option: 2]
|
import Temple.Html, only: [option: 2]
|
||||||
|
|
||||||
defelement(:my_select, :nonvoid)
|
defelement(:my_select, :nonvoid)
|
||||||
defelement(:my_input, :void)
|
defelement(:my_input, :void)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
defmodule Temple.TagsTest do
|
defmodule Temple.HtmlTest do
|
||||||
use ExUnit.Case, async: true
|
use ExUnit.Case, async: true
|
||||||
use Temple
|
use Temple
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ defmodule Temple.TagsTest do
|
||||||
assert result == ~s{<!DOCTYPE html><html class="hello"><div></div></html>}
|
assert result == ~s{<!DOCTYPE html><html class="hello"><div></div></html>}
|
||||||
end
|
end
|
||||||
|
|
||||||
for tag <- Temple.Tags.nonvoid_elements() do
|
for tag <- Temple.Html.nonvoid_elements() do
|
||||||
test "renders a #{tag}" do
|
test "renders a #{tag}" do
|
||||||
{:safe, result} =
|
{:safe, result} =
|
||||||
temple do
|
temple do
|
||||||
|
@ -92,7 +92,7 @@ defmodule Temple.TagsTest do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for tag <- Temple.Tags.void_elements() do
|
for tag <- Temple.Html.void_elements() do
|
||||||
test "renders a #{tag}" do
|
test "renders a #{tag}" do
|
||||||
{:safe, result} =
|
{:safe, result} =
|
||||||
temple do
|
temple do
|
150
test/temple/svg_test.exs
Normal file
150
test/temple/svg_test.exs
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
defmodule Temple.SvgTest do
|
||||||
|
use ExUnit.Case, async: true
|
||||||
|
import Temple
|
||||||
|
import Temple.Svg
|
||||||
|
import Temple.Utils, only: [to_valid_tag: 1]
|
||||||
|
|
||||||
|
for tag <- Temple.Svg.elements() -- [:text_] do
|
||||||
|
test "renders a #{tag}" do
|
||||||
|
{:safe, result} =
|
||||||
|
temple do
|
||||||
|
unquote(tag)()
|
||||||
|
end
|
||||||
|
|
||||||
|
assert result == ~s{<#{to_valid_tag(unquote(tag))}></#{to_valid_tag(unquote(tag))}>}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "renders a #{tag} with attrs" do
|
||||||
|
{:safe, result} =
|
||||||
|
temple do
|
||||||
|
unquote(tag)(class: "hello")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert result ==
|
||||||
|
~s{<#{to_valid_tag(unquote(tag))} class="hello"></#{to_valid_tag(unquote(tag))}>}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "renders a #{tag} with content" do
|
||||||
|
{:safe, result} =
|
||||||
|
temple do
|
||||||
|
unquote(tag)("Hi")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert result == "<#{to_valid_tag(unquote(tag))}>Hi</#{to_valid_tag(unquote(tag))}>"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "renders a #{tag} with escaped content" do
|
||||||
|
{:safe, result} =
|
||||||
|
temple do
|
||||||
|
unquote(tag)("<div>1</div>")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert result ==
|
||||||
|
"<#{to_valid_tag(unquote(tag))}><div>1</div></#{
|
||||||
|
to_valid_tag(unquote(tag))
|
||||||
|
}>"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "renders a #{tag} with attrs and content" do
|
||||||
|
{:safe, result} =
|
||||||
|
temple do
|
||||||
|
unquote(tag)("Hi", class: "hello")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert result ==
|
||||||
|
~s{<#{to_valid_tag(unquote(tag))} class="hello">Hi</#{to_valid_tag(unquote(tag))}>}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "renders a #{tag} with a block" do
|
||||||
|
{:safe, result} =
|
||||||
|
temple do
|
||||||
|
unquote(tag)(do: unquote(tag)())
|
||||||
|
end
|
||||||
|
|
||||||
|
assert result ==
|
||||||
|
~s{<#{to_valid_tag(unquote(tag))}><#{to_valid_tag(unquote(tag))}></#{
|
||||||
|
to_valid_tag(unquote(tag))
|
||||||
|
}></#{to_valid_tag(unquote(tag))}>}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "renders a #{tag} with attrs and a block" do
|
||||||
|
{:safe, result} =
|
||||||
|
temple do
|
||||||
|
unquote(tag)(class: "hello") do
|
||||||
|
unquote(tag)()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert result ==
|
||||||
|
~s{<#{to_valid_tag(unquote(tag))} class="hello"><#{to_valid_tag(unquote(tag))}></#{
|
||||||
|
to_valid_tag(unquote(tag))
|
||||||
|
}></#{to_valid_tag(unquote(tag))}>}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "renders a text" do
|
||||||
|
{:safe, result} =
|
||||||
|
temple do
|
||||||
|
text_()
|
||||||
|
end
|
||||||
|
|
||||||
|
assert result == ~s{<text></text>}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "renders a text with attrs" do
|
||||||
|
{:safe, result} =
|
||||||
|
temple do
|
||||||
|
text_(class: "hello")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert result == ~s{<text class="hello"></text>}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "renders a text with content" do
|
||||||
|
{:safe, result} =
|
||||||
|
temple do
|
||||||
|
text_("Hi")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert result == "<text>Hi</text>"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "renders a text with escaped content" do
|
||||||
|
{:safe, result} =
|
||||||
|
temple do
|
||||||
|
text_("<div>1</div>")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert result == "<text><div>1</div></text>"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "renders a text with attrs and content" do
|
||||||
|
{:safe, result} =
|
||||||
|
temple do
|
||||||
|
text_("Hi", class: "hello")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert result == ~s{<text class="hello">Hi</text>}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "renders a text with a block" do
|
||||||
|
{:safe, result} =
|
||||||
|
temple do
|
||||||
|
text_(do: text_())
|
||||||
|
end
|
||||||
|
|
||||||
|
assert result == ~s{<text><text></text></text>}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "renders a text with attrs and a block" do
|
||||||
|
{:safe, result} =
|
||||||
|
temple do
|
||||||
|
text_(class: "hello") do
|
||||||
|
text_()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert result ==
|
||||||
|
~s{<text class="hello"><text></text></text>}
|
||||||
|
end
|
||||||
|
end
|
Reference in a new issue