SVG (#181)
This basically just adds svg elements as void and nonvoid element aliases and it works, will test on a real proejct before releasing the next release. Also, fixed the weird behaviour problem by defining types for each of the ast nodes and then referencing those types when defining the ast type. Unclear why this works, but I imagine it has to do with the types not being a big part of the compilation process or something. This also uses the typed_struct library to do so. Seems pretty slick and does what it claims it does.
This commit is contained in:
parent
f9ccfbc718
commit
99cbb42962
116
.formatter.exs
116
.formatter.exs
|
@ -1,5 +1,6 @@
|
|||
locals_without_parens = ~w[
|
||||
temple c slot
|
||||
temple = ~w[temple c slot]a
|
||||
|
||||
html = ~w[
|
||||
html head title style script
|
||||
noscript template
|
||||
body section nav article aside h1 h2 h3 h4 h5 h6
|
||||
|
@ -12,22 +13,113 @@ locals_without_parens = ~w[
|
|||
map svg math
|
||||
table caption colgroup tbody thead tfoot tr td th
|
||||
form fieldset legend label button select datalist optgroup
|
||||
option text_area output progress meter
|
||||
option textarea output progress meter
|
||||
details summary menuitem menu
|
||||
meta link base
|
||||
area br col embed hr img input keygen param source track wbr
|
||||
]a
|
||||
|
||||
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
|
||||
]a |> Enum.map(fn e -> {e, :*} end)
|
||||
svg = ~w[
|
||||
circle
|
||||
ellipse
|
||||
line
|
||||
path
|
||||
polygon
|
||||
polyline
|
||||
rect
|
||||
stop
|
||||
use
|
||||
a
|
||||
altGlyph
|
||||
altGlyphDef
|
||||
altGlyphItem
|
||||
animate
|
||||
animateColor
|
||||
animateMotion
|
||||
animateTransform
|
||||
animation
|
||||
audio
|
||||
canvas
|
||||
clipPath
|
||||
cursor
|
||||
defs
|
||||
desc
|
||||
discard
|
||||
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
|
||||
font
|
||||
foreignObject
|
||||
g
|
||||
glyph
|
||||
glyphRef
|
||||
handler
|
||||
hatch
|
||||
hatchpath
|
||||
hkern
|
||||
iframe
|
||||
image
|
||||
linearGradient
|
||||
listener
|
||||
marker
|
||||
mask
|
||||
mesh
|
||||
meshgradient
|
||||
meshpatch
|
||||
meshrow
|
||||
metadata
|
||||
mpath
|
||||
pattern
|
||||
prefetch
|
||||
radialGradient
|
||||
script
|
||||
set
|
||||
solidColor
|
||||
solidcolor
|
||||
style
|
||||
svg
|
||||
switch
|
||||
symbol
|
||||
tbreak
|
||||
text
|
||||
textArea
|
||||
textPath
|
||||
title
|
||||
tref
|
||||
tspan
|
||||
unknown
|
||||
video
|
||||
view
|
||||
vkern
|
||||
]a
|
||||
|
||||
locals_without_parens = Enum.map(temple ++ html ++ svg, &{&1, :*})
|
||||
|
||||
[
|
||||
import_deps: [:typed_struct],
|
||||
inputs: ["*.{ex,exs}", "{config,lib,test}/**/*.{ex,exs}"],
|
||||
locals_without_parens: locals_without_parens,
|
||||
export: [locals_without_parens: locals_without_parens]
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
> You are looking at the README for the main branch. The README for the latest stable release is located [here](https://github.com/mhanberg/temple/tree/v0.9.0).
|
||||
|
||||
Temple is an Elixir DSL for writing HTML.
|
||||
Temple is an Elixir DSL for writing HTML and SVG.
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
defmodule Temple.Ast do
|
||||
@moduledoc false
|
||||
|
||||
@type t ::
|
||||
Temple.Parser.Empty.t()
|
||||
| Temple.Parser.Text.t()
|
||||
| Temple.Parser.Components.t()
|
||||
| Temple.Parser.Slot.t()
|
||||
| Temple.Parser.NonvoidElementsAliases.t()
|
||||
| Temple.Parser.VoidElementsAliases.t()
|
||||
| Temple.Parser.AnonymousFunctions.t()
|
||||
| Temple.Parser.RightArrow.t()
|
||||
| Temple.Parser.DoExpressions.t()
|
||||
| Temple.Parser.Match.t()
|
||||
| Temple.Parser.Default.t()
|
||||
|
||||
def new(module, opts \\ []) do
|
||||
struct(module, opts)
|
||||
end
|
||||
|
|
|
@ -1,32 +1,21 @@
|
|||
defmodule Temple.Parser do
|
||||
@moduledoc false
|
||||
|
||||
alias Temple.Parser.AnonymousFunctions
|
||||
alias Temple.Parser.Components
|
||||
alias Temple.Parser.Default
|
||||
alias Temple.Parser.DoExpressions
|
||||
alias Temple.Parser.Empty
|
||||
alias Temple.Parser.Text
|
||||
alias Temple.Parser.Match
|
||||
alias Temple.Parser.NonvoidElementsAliases
|
||||
alias Temple.Parser.RightArrow
|
||||
alias Temple.Parser.Slot
|
||||
alias Temple.Parser.TempleNamespaceNonvoid
|
||||
alias Temple.Parser.TempleNamespaceVoid
|
||||
alias Temple.Parser.Components
|
||||
alias Temple.Parser.Slot
|
||||
alias Temple.Parser.NonvoidElementsAliases
|
||||
alias Temple.Parser.Text
|
||||
alias Temple.Parser.VoidElementsAliases
|
||||
alias Temple.Parser.AnonymousFunctions
|
||||
alias Temple.Parser.RightArrow
|
||||
alias Temple.Parser.DoExpressions
|
||||
alias Temple.Parser.Match
|
||||
alias Temple.Parser.Default
|
||||
|
||||
@type ast ::
|
||||
%Empty{}
|
||||
| %Text{}
|
||||
| %Components{}
|
||||
| %Slot{}
|
||||
| %NonvoidElementsAliases{}
|
||||
| %VoidElementsAliases{}
|
||||
| %AnonymousFunctions{}
|
||||
| %RightArrow{}
|
||||
| %DoExpressions{}
|
||||
| %Match{}
|
||||
| %Default{}
|
||||
@aliases Application.compile_env(:temple, :aliases, [])
|
||||
|
||||
@doc """
|
||||
Should return true if the parser should apply for the given AST.
|
||||
|
@ -38,9 +27,113 @@ defmodule Temple.Parser do
|
|||
|
||||
Should return Temple.AST.
|
||||
"""
|
||||
@callback run(ast :: Macro.t()) :: ast()
|
||||
@callback run(ast :: Macro.t()) :: Temple.Ast.t()
|
||||
|
||||
@aliases Application.get_env(:temple, :aliases, [])
|
||||
@void_svg_lookup [
|
||||
circle: "circle",
|
||||
ellipse: "ellipse",
|
||||
line: "line",
|
||||
path: "path",
|
||||
polygon: "polygon",
|
||||
polyline: "polyline",
|
||||
rect: "rect",
|
||||
stop: "stop",
|
||||
use: "use"
|
||||
]
|
||||
|
||||
@void_svg_aliases Keyword.keys(@void_svg_lookup)
|
||||
|
||||
@nonvoid_svg_lookup [
|
||||
a: "a",
|
||||
altGlyph: "altGlyph",
|
||||
altGlyphDef: "altGlyphDef",
|
||||
altGlyphItem: "altGlyphItem",
|
||||
animate: "animate",
|
||||
animateColor: "animateColor",
|
||||
animateMotion: "animateMotion",
|
||||
animateTransform: "animateTransform",
|
||||
animation: "animation",
|
||||
audio: "audio",
|
||||
canvas: "canvas",
|
||||
clipPath: "clipPath",
|
||||
cursor: "cursor",
|
||||
defs: "defs",
|
||||
desc: "desc",
|
||||
discard: "discard",
|
||||
feBlend: "feBlend",
|
||||
feColorMatrix: "feColorMatrix",
|
||||
feComponentTransfer: "feComponentTransfer",
|
||||
feComposite: "feComposite",
|
||||
feConvolveMatrix: "feConvolveMatrix",
|
||||
feDiffuseLighting: "feDiffuseLighting",
|
||||
feDisplacementMap: "feDisplacementMap",
|
||||
feDistantLight: "feDistantLight",
|
||||
feDropShadow: "feDropShadow",
|
||||
feFlood: "feFlood",
|
||||
feFuncA: "feFuncA",
|
||||
feFuncB: "feFuncB",
|
||||
feFuncG: "feFuncG",
|
||||
feFuncR: "feFuncR",
|
||||
feGaussianBlur: "feGaussianBlur",
|
||||
feImage: "feImage",
|
||||
feMerge: "feMerge",
|
||||
feMergeNode: "feMergeNode",
|
||||
feMorphology: "feMorphology",
|
||||
feOffset: "feOffset",
|
||||
fePointLight: "fePointLight",
|
||||
feSpecularLighting: "feSpecularLighting",
|
||||
feSpotLight: "feSpotLight",
|
||||
feTile: "feTile",
|
||||
feTurbulence: "feTurbulence",
|
||||
filter: "filter",
|
||||
font: "font",
|
||||
foreignObject: "foreignObject",
|
||||
g: "g",
|
||||
glyph: "glyph",
|
||||
glyphRef: "glyphRef",
|
||||
handler: "handler",
|
||||
hatch: "hatch",
|
||||
hatchpath: "hatchpath",
|
||||
hkern: "hkern",
|
||||
iframe: "iframe",
|
||||
image: "image",
|
||||
linearGradient: "linearGradient",
|
||||
listener: "listener",
|
||||
marker: "marker",
|
||||
mask: "mask",
|
||||
mesh: "mesh",
|
||||
meshgradient: "meshgradient",
|
||||
meshpatch: "meshpatch",
|
||||
meshrow: "meshrow",
|
||||
metadata: "metadata",
|
||||
mpath: "mpath",
|
||||
pattern: "pattern",
|
||||
prefetch: "prefetch",
|
||||
radialGradient: "radialGradient",
|
||||
script: "script",
|
||||
set: "set",
|
||||
solidColor: "solidColor",
|
||||
solidcolor: "solidcolor",
|
||||
style: "style",
|
||||
svg: "svg",
|
||||
switch: "switch",
|
||||
symbol: "symbol",
|
||||
tbreak: "tbreak",
|
||||
text: "text",
|
||||
textArea: "textArea",
|
||||
textPath: "textPath",
|
||||
title: "title",
|
||||
tref: "tref",
|
||||
tspan: "tspan",
|
||||
unknown: "unknown",
|
||||
video: "video",
|
||||
view: "view",
|
||||
vkern: "vkern"
|
||||
]
|
||||
|
||||
@nonvoid_svg_aliases Keyword.keys(@nonvoid_svg_lookup)
|
||||
|
||||
# nonvoid tags
|
||||
|
||||
@nonvoid_elements ~w[
|
||||
head title style script
|
||||
|
@ -67,9 +160,9 @@ defmodule Temple.Parser do
|
|||
{Keyword.get(@aliases, el, el), el}
|
||||
end)
|
||||
|
||||
def nonvoid_elements, do: @nonvoid_elements
|
||||
def nonvoid_elements_aliases, do: @nonvoid_elements_aliases
|
||||
def nonvoid_elements_lookup, do: @nonvoid_elements_lookup
|
||||
def nonvoid_elements, do: @nonvoid_elements ++ Keyword.values(@nonvoid_svg_aliases)
|
||||
def nonvoid_elements_aliases, do: @nonvoid_elements_aliases ++ @nonvoid_svg_aliases
|
||||
def nonvoid_elements_lookup, do: @nonvoid_elements_lookup ++ @nonvoid_svg_lookup
|
||||
|
||||
@void_elements ~w[
|
||||
meta link base
|
||||
|
@ -81,9 +174,9 @@ defmodule Temple.Parser do
|
|||
{Keyword.get(@aliases, el, el), el}
|
||||
end)
|
||||
|
||||
def void_elements, do: @void_elements
|
||||
def void_elements_aliases, do: @void_elements_aliases
|
||||
def void_elements_lookup, do: @void_elements_lookup
|
||||
def void_elements, do: @void_elements ++ Keyword.values(@void_svg_aliases)
|
||||
def void_elements_aliases, do: @void_elements_aliases ++ @void_svg_aliases
|
||||
def void_elements_lookup, do: @void_elements_lookup ++ @void_svg_lookup
|
||||
|
||||
def parsers() do
|
||||
[
|
||||
|
|
|
@ -2,11 +2,14 @@ defmodule Temple.Parser.AnonymousFunctions do
|
|||
@moduledoc false
|
||||
@behaviour Temple.Parser
|
||||
|
||||
defstruct elixir_ast: nil, children: []
|
||||
use TypedStruct
|
||||
|
||||
alias Temple.Parser
|
||||
typedstruct do
|
||||
field :elixir_ast, Macro.t()
|
||||
field :children, [map()]
|
||||
end
|
||||
|
||||
@impl Parser
|
||||
@impl true
|
||||
def applicable?({_, _, args}) do
|
||||
import Temple.Parser.Utils, only: [split_args: 1]
|
||||
|
||||
|
@ -18,7 +21,7 @@ defmodule Temple.Parser.AnonymousFunctions do
|
|||
|
||||
def applicable?(_), do: false
|
||||
|
||||
@impl Parser
|
||||
@impl true
|
||||
def run({_name, _, args} = expression) do
|
||||
{_do_and_else, args} = Temple.Parser.Utils.split_args(args)
|
||||
|
||||
|
|
|
@ -2,16 +2,23 @@ defmodule Temple.Parser.Components do
|
|||
@moduledoc false
|
||||
@behaviour Temple.Parser
|
||||
|
||||
defstruct function: nil, assigns: [], children: [], slots: []
|
||||
use TypedStruct
|
||||
|
||||
@impl Temple.Parser
|
||||
typedstruct do
|
||||
field :function, function()
|
||||
field :assigns, map()
|
||||
field :children, [map()]
|
||||
field :slots, [function()]
|
||||
end
|
||||
|
||||
@impl true
|
||||
def applicable?({:c, _, _}) do
|
||||
true
|
||||
end
|
||||
|
||||
def applicable?(_), do: false
|
||||
|
||||
@impl Temple.Parser
|
||||
@impl true
|
||||
def run({:c, _meta, [component_function | args]}) do
|
||||
{do_and_else, args} =
|
||||
args
|
||||
|
|
|
@ -2,14 +2,16 @@ defmodule Temple.Parser.Default do
|
|||
@moduledoc false
|
||||
@behaviour Temple.Parser
|
||||
|
||||
defstruct elixir_ast: nil
|
||||
use TypedStruct
|
||||
|
||||
alias Temple.Parser
|
||||
typedstruct do
|
||||
field :elixir_ast, Macro.t()
|
||||
end
|
||||
|
||||
@impl Parser
|
||||
@impl true
|
||||
def applicable?(_ast), do: true
|
||||
|
||||
@impl Parser
|
||||
@impl true
|
||||
def run(ast) do
|
||||
Temple.Ast.new(__MODULE__, elixir_ast: ast)
|
||||
end
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
defmodule Temple.Parser.DoExpressions do
|
||||
@moduledoc false
|
||||
alias Temple.Parser
|
||||
@behaviour Temple.Parser
|
||||
|
||||
@behaviour Parser
|
||||
use TypedStruct
|
||||
|
||||
defstruct elixir_ast: nil, children: []
|
||||
typedstruct do
|
||||
field :elixir_ast, Macro.t()
|
||||
field :children, [map()]
|
||||
end
|
||||
|
||||
@impl Parser
|
||||
@impl true
|
||||
def applicable?({_, _, args}) when is_list(args) do
|
||||
Enum.any?(args, fn arg -> match?([{:do, _} | _], arg) end)
|
||||
end
|
||||
|
||||
def applicable?(_), do: false
|
||||
|
||||
@impl Parser
|
||||
@impl true
|
||||
def run({name, meta, args}) do
|
||||
{do_and_else, args} = Temple.Parser.Utils.split_args(args)
|
||||
|
||||
|
|
|
@ -3,12 +3,17 @@ defmodule Temple.Parser.ElementList do
|
|||
|
||||
@behaviour Temple.Parser
|
||||
|
||||
defstruct children: [], whitespace: :loose
|
||||
use TypedStruct
|
||||
|
||||
@impl Temple.Parser
|
||||
typedstruct do
|
||||
field :children, list()
|
||||
field :whitespace, :loose | :tight
|
||||
end
|
||||
|
||||
@impl true
|
||||
def applicable?(asts), do: is_list(asts)
|
||||
|
||||
@impl Temple.Parser
|
||||
@impl true
|
||||
def run(asts) do
|
||||
children = Enum.flat_map(asts, &Temple.Parser.parse/1)
|
||||
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
defmodule Temple.Parser.Empty do
|
||||
@moduledoc false
|
||||
|
||||
use TypedStruct
|
||||
|
||||
@behaviour Temple.Parser
|
||||
|
||||
defstruct []
|
||||
typedstruct do
|
||||
end
|
||||
|
||||
alias Temple.Parser
|
||||
|
||||
@impl Parser
|
||||
@impl true
|
||||
def applicable?(ast) when ast in [nil, []], do: true
|
||||
def applicable?(_), do: false
|
||||
|
||||
@impl Parser
|
||||
@impl true
|
||||
def run(_ast) do
|
||||
Temple.Ast.new(__MODULE__)
|
||||
end
|
||||
|
|
|
@ -2,18 +2,20 @@ defmodule Temple.Parser.Match do
|
|||
@moduledoc false
|
||||
@behaviour Temple.Parser
|
||||
|
||||
defstruct elixir_ast: nil
|
||||
use TypedStruct
|
||||
|
||||
alias Temple.Parser
|
||||
typedstruct do
|
||||
field :elixir_ast, Macro.t()
|
||||
end
|
||||
|
||||
@impl Parser
|
||||
@impl true
|
||||
def applicable?({name, _, _}) do
|
||||
name in [:=]
|
||||
end
|
||||
|
||||
def applicable?(_), do: false
|
||||
|
||||
@impl Parser
|
||||
@impl true
|
||||
def run(macro) do
|
||||
Temple.Ast.new(__MODULE__, elixir_ast: macro)
|
||||
end
|
||||
|
|
|
@ -2,18 +2,25 @@ defmodule Temple.Parser.NonvoidElementsAliases do
|
|||
@moduledoc false
|
||||
@behaviour Temple.Parser
|
||||
|
||||
defstruct name: nil, attrs: [], children: [], meta: %{}
|
||||
use TypedStruct
|
||||
|
||||
typedstruct do
|
||||
field :name, atom()
|
||||
field :attrs, list()
|
||||
field :children, list()
|
||||
field :meta, map()
|
||||
end
|
||||
|
||||
alias Temple.Parser
|
||||
|
||||
@impl Parser
|
||||
@impl true
|
||||
def applicable?({name, _, _}) do
|
||||
name in Parser.nonvoid_elements_aliases()
|
||||
end
|
||||
|
||||
def applicable?(_), do: false
|
||||
|
||||
@impl Parser
|
||||
@impl true
|
||||
def run({name, meta, args}) do
|
||||
name = Parser.nonvoid_elements_lookup()[name]
|
||||
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
defmodule Temple.Parser.RightArrow do
|
||||
@moduledoc false
|
||||
alias Temple.Parser
|
||||
|
||||
@behaviour Parser
|
||||
@behaviour Temple.Parser
|
||||
|
||||
defstruct elixir_ast: nil, children: []
|
||||
use TypedStruct
|
||||
|
||||
@impl Parser
|
||||
typedstruct do
|
||||
field :elixir_ast, Macro.t()
|
||||
field :children, [map()]
|
||||
end
|
||||
|
||||
@impl true
|
||||
def applicable?({:->, _, _}), do: true
|
||||
def applicable?(_), do: false
|
||||
|
||||
@impl Parser
|
||||
@impl true
|
||||
def run({func, meta, [pattern, args]}) do
|
||||
children = Parser.parse(args)
|
||||
children = Temple.Parser.parse(args)
|
||||
|
||||
Temple.Ast.new(__MODULE__, elixir_ast: {func, meta, [pattern]}, children: children)
|
||||
end
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
defmodule Temple.Parser.Slot do
|
||||
@moduledoc false
|
||||
@behaviour Temple.Parser
|
||||
use TypedStruct
|
||||
|
||||
defstruct name: nil, args: []
|
||||
typedstruct do
|
||||
field :name, atom()
|
||||
field :args, list(), default: []
|
||||
end
|
||||
|
||||
@impl true
|
||||
def applicable?({:slot, _, _}) do
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
defmodule Temple.Parser.Slottable do
|
||||
@moduledoc false
|
||||
|
||||
defstruct content: nil, assigns: Macro.escape(%{}), name: nil
|
||||
use TypedStruct
|
||||
|
||||
typedstruct do
|
||||
field :content, any()
|
||||
field :assigns, map(), default: Macro.escape(%{})
|
||||
field :name, atom()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,14 +4,14 @@ defmodule Temple.Parser.TempleNamespaceNonvoid do
|
|||
|
||||
alias Temple.Parser
|
||||
|
||||
@impl Parser
|
||||
@impl true
|
||||
def applicable?({{:., _, [{:__aliases__, _, [:Temple]}, name]}, _meta, _args}) do
|
||||
name in Parser.nonvoid_elements_aliases()
|
||||
end
|
||||
|
||||
def applicable?(_), do: false
|
||||
|
||||
@impl Parser
|
||||
@impl true
|
||||
def run({name, meta, args}) do
|
||||
{:., _, [{:__aliases__, _, [:Temple]}, name]} = name
|
||||
Temple.Parser.NonvoidElementsAliases.run({name, meta, args})
|
||||
|
|
|
@ -2,14 +2,14 @@ defmodule Temple.Parser.TempleNamespaceVoid do
|
|||
@moduledoc false
|
||||
@behaviour Temple.Parser
|
||||
|
||||
@impl Temple.Parser
|
||||
@impl true
|
||||
def applicable?({{:., _, [{:__aliases__, _, [:Temple]}, name]}, _meta, _args}) do
|
||||
name in Temple.Parser.void_elements_aliases()
|
||||
end
|
||||
|
||||
def applicable?(_), do: false
|
||||
|
||||
@impl Temple.Parser
|
||||
@impl true
|
||||
def run({name, meta, args}) do
|
||||
{:., _, [{:__aliases__, _, [:Temple]}, name]} = name
|
||||
|
||||
|
|
|
@ -2,15 +2,17 @@ defmodule Temple.Parser.Text do
|
|||
@moduledoc false
|
||||
@behaviour Temple.Parser
|
||||
|
||||
defstruct text: nil
|
||||
use TypedStruct
|
||||
|
||||
alias Temple.Parser
|
||||
typedstruct do
|
||||
field :text, String.t()
|
||||
end
|
||||
|
||||
@impl Parser
|
||||
@impl true
|
||||
def applicable?(text) when is_binary(text), do: true
|
||||
def applicable?(_), do: false
|
||||
|
||||
@impl Parser
|
||||
@impl true
|
||||
def run(text) do
|
||||
Temple.Ast.new(__MODULE__, text: text)
|
||||
end
|
||||
|
|
|
@ -2,16 +2,21 @@ defmodule Temple.Parser.VoidElementsAliases do
|
|||
@moduledoc false
|
||||
@behaviour Temple.Parser
|
||||
|
||||
defstruct name: nil, attrs: []
|
||||
use TypedStruct
|
||||
|
||||
@impl Temple.Parser
|
||||
typedstruct do
|
||||
field :name, atom()
|
||||
field :attrs, list(), default: []
|
||||
end
|
||||
|
||||
@impl true
|
||||
def applicable?({name, _, _}) do
|
||||
name in Temple.Parser.void_elements_aliases()
|
||||
end
|
||||
|
||||
def applicable?(_), do: false
|
||||
|
||||
@impl Temple.Parser
|
||||
@impl true
|
||||
def run({name, _, args}) do
|
||||
args =
|
||||
case Temple.Parser.Utils.split_args(args) do
|
||||
|
|
1
mix.exs
1
mix.exs
|
@ -61,6 +61,7 @@ defmodule Temple.MixProject do
|
|||
|
||||
defp deps do
|
||||
[
|
||||
{:typed_struct, "~> 0.3"},
|
||||
{:floki, ">= 0.0.0"},
|
||||
{:ex_doc, "~> 0.28.3", only: :dev, runtime: false}
|
||||
]
|
||||
|
|
1
mix.lock
1
mix.lock
|
@ -7,4 +7,5 @@
|
|||
"makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"},
|
||||
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
|
||||
"nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"},
|
||||
"typed_struct": {:hex, :typed_struct, "0.3.0", "939789e3c1dca39d7170c87f729127469d1315dcf99fee8e152bb774b17e7ff7", [:mix], [], "hexpm", "c50bd5c3a61fe4e198a8504f939be3d3c85903b382bde4865579bc23111d1b6d"},
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ defmodule Temple.ConverterTest do
|
|||
</style>
|
||||
"""
|
||||
|
||||
assert Converter.convert(html) |> tap(&IO.puts/1) ===
|
||||
assert Converter.convert(html) ===
|
||||
"""
|
||||
script do
|
||||
"console.log(\\"ayy yoo\\");"
|
||||
|
|
Reference in a new issue