Current section
Files
Jump to
Current section
Files
lib/simple_form.ex
defmodule SimpleForm do
@moduledoc """
`SimpleForm` provides a simple representation and manipulation of structured elements,
similar to HTML or XML, using Elixir tuples and lists.
## Overview
A `SimpleForm.element()` is represented as:
{tag_name, attributes, content}
Where:
- `tag_name` is a string representing the name of the element.
- `attributes` is a list of key-value tuples defining element attributes.
- `content` is a list containing strings (text content) or nested elements.
"""
@type tag_name() :: String.t()
@type content() :: [String.t() | element()]
@type attribute() :: {key :: String.t(), value :: String.t()}
@type element() :: {tag_name(), [attribute()], content()}
@doc """
Checks if value is an element.
## Examples
iex> SimpleForm.element?(true)
false
iex> SimpleForm.element?({"p", [{"class", "intro"}], [{"strong", [], ["Hello"]}, " world!"]})
true
iex> SimpleForm.element?({"class", "strong"})
false
iex> SimpleForm.element?("Hello World!")
false
"""
@spec element?(value :: term()) :: boolean()
def element?({tag_name, attributes, content})
when is_binary(tag_name) and is_list(attributes) and is_list(content) do
Enum.all?(attributes, &attribute?/1) and Enum.all?(content, &content?/1)
end
def element?(_),
do: false
@doc """
Checks if value is an attribute.
## Examples
iex> SimpleForm.attribute?(true)
false
iex> SimpleForm.attribute?({"p", [{"class", "intro"}], [{"strong", [], ["Hello"]}, " world!"]})
false
iex> SimpleForm.attribute?({"class", "strong"})
true
iex> SimpleForm.attribute?("Hello World!")
false
"""
@spec attribute?(value :: term()) :: boolean()
def attribute?({name, value}) when is_binary(name) and is_binary(value),
do: true
def attribute?(_),
do: false
@doc """
Checks if value is content.
## Examples
iex> SimpleForm.content?(true)
false
iex> SimpleForm.content?({"p", [{"class", "intro"}], [{"strong", [], ["Hello"]}, " world!"]})
true
iex> SimpleForm.content?({"class", "strong"})
false
iex> SimpleForm.content?("Hello World!")
true
"""
@spec content?(value :: term()) :: boolean()
def content?(content) when is_binary(content),
do: true
def content?(value),
do: element?(value)
end