Packages
mdex
0.11.2
0.13.3
0.13.2
0.13.1
0.13.0
0.12.5
retired
0.12.4
0.12.3
0.12.2
0.12.1
0.12.0
0.11.7
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.2
0.6.1
0.6.0
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
0.1.18
0.1.17
0.1.16
0.1.15
0.1.14
0.1.13
0.1.12
0.1.11
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Fast and extensible Markdown for Elixir
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/mdex/document/access.ex
defmodule MDEx.Document.Access do
@moduledoc false
defmacro __using__(_opts) do
quote do
@doc false
defdelegate fetch(document, selector), to: MDEx.Document.Access
@doc false
defdelegate get_and_update(paragraph, selector, fun), to: MDEx.Document.Access
@doc false
defdelegate pop(document, key, default), to: MDEx.Document.Access
end
end
def fetch(document, selector)
def fetch(document, selector) when is_struct(selector) do
case Enum.filter(document, fn node -> node == selector end) do
[] -> :error
node -> {:ok, node}
end
end
def fetch(document, selector) when is_atom(selector) do
selector = modulefy!(selector)
case Enum.filter(document, fn %{__struct__: mod} -> mod == selector end) do
[] -> :error
node -> {:ok, node}
end
end
def fetch(document, selector) when is_function(selector, 1) do
case Enum.filter(document, selector) do
[] -> :error
node -> {:ok, node}
end
end
def fetch(document, selector) when is_integer(selector) do
case Enum.at(document, selector) do
nil -> :error
node -> {:ok, node}
end
end
def get_and_update(document, selector, fun) when is_struct(selector) do
{document, {_, old}} =
MDEx.Document.Traversal.traverse_and_update(document, {:cont, nil}, fn
node, {:halted, old} ->
{node, {:halted, old}}
^selector, {:cont, _old} ->
{old, new} = fun.(selector)
{new, {:halted, old}}
node, acc ->
{node, acc}
end)
{old, document}
end
def get_and_update(document, selector, fun) when is_atom(selector) do
selector = modulefy!(selector)
{document, {_, old}} =
MDEx.Document.Traversal.traverse_and_update(document, {:cont, nil}, fn
node, {:halted, old} ->
{node, {:halted, old}}
%{__struct__: mod} = node, {:cont, _old} = acc ->
if mod == selector do
{old, new} = fun.(node)
{new, {:halted, old}}
else
{node, acc}
end
node, acc ->
{node, acc}
end)
{old, document}
end
def get_and_update(document, selector, fun) when is_function(selector) do
{document, {_, old}} =
MDEx.Document.Traversal.traverse_and_update(document, {:cont, nil}, fn
node, {:halted, old} ->
{node, {:halted, old}}
node, acc ->
if selector.(node) do
{old, new} = fun.(node)
{new, {:halted, old}}
else
{node, acc}
end
end)
{old, document}
end
def get_and_update(document, selector, fun) when is_integer(selector) do
node = Enum.at(document, selector)
if node do
{old, _new} = fun.(node)
{old, document}
else
{nil, document}
end
end
def pop(document, key, default \\ nil)
def pop(document, key, default) when is_struct(key) do
{new, {_, old}} =
MDEx.Document.Traversal.traverse_and_update(document, {:cont, nil}, fn
node, {:halted, old} ->
{node, {:halted, old}}
^key, {:cont, _} ->
{:pop, {:halted, key}}
node, acc ->
{node, acc}
end)
{old || default, new}
end
def pop(document, key, default) when is_atom(key) do
key = modulefy!(key)
{new, {_, old}} =
MDEx.Document.Traversal.traverse_and_update(document, {:cont, nil}, fn
node, {:halted, old} ->
{node, {:halted, old}}
%{__struct__: mod} = node, {:cont, _} = acc ->
if mod == key do
{:pop, {:halted, node}}
else
{node, acc}
end
node, acc ->
{node, acc}
end)
{old || default, new}
end
def pop(document, key, default) when is_integer(key) do
node = Enum.at(document, key)
{node || default, document}
end
@doc false
def modulefy!(nil = _selector), do: raise(%MDEx.InvalidSelector{selector: nil})
def modulefy!(selector) when is_atom(selector) do
case Atom.to_string(selector) do
"Elixir." <> name -> Module.concat([name])
atom -> Module.concat(["MDEx", Macro.camelize(atom)])
end
end
def modulefy!(selector), do: raise(%MDEx.InvalidSelector{selector: selector})
end