Packages

An HTML templating engine that uses XML/HTML tag syntax to render HTML.

Current section

Files

Jump to
tagg src section.erl
Raw

src/section.erl

-module(section).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([get_attrs/1, get_sections_rec/4, get_sections/1]).
-export_type([section/0]).
-type section() :: {text, binary(), integer(), cx:context()} |
{tag,
binary(),
gleam@dict:dict(binary(), binary()),
list(section()),
integer(),
cx:context()}.
-spec get_attrs_rec(binary(), gleam@dict:dict(binary(), binary())) -> gleam@dict:dict(binary(), binary()).
get_attrs_rec(S, Acc) ->
{Attr_name, S1, _} = grapheme_util:get_name_ignore_ws(S),
case Attr_name of
<<""/utf8>> ->
Acc;
_ ->
case S1 of
<<"="/utf8, S2/binary>> ->
{_, S3} = grapheme_util:get_whitespace(S2),
case S3 of
<<"\""/utf8, S4/binary>> ->
{Attr_value, S5} = grapheme_util:get_chars_matching_func(
S4,
<<""/utf8>>,
fun grapheme_util:is_not_double_quote/1
),
case S5 of
<<"\""/utf8, Rest/binary>> ->
get_attrs_rec(
Rest,
begin
_pipe = Acc,
gleam@dict:insert(
_pipe,
Attr_name,
Attr_value
)
end
);
_ ->
logging:log(
error,
<<"Expected end double quote for attribute name: "/utf8,
Attr_name/binary>>
),
Acc
end;
<<"'"/utf8, S4@1/binary>> ->
{Attr_value@1, S5@1} = grapheme_util:get_chars_matching_func(
S4@1,
<<""/utf8>>,
fun grapheme_util:is_not_single_quote/1
),
case S5@1 of
<<"'"/utf8, Rest@1/binary>> ->
get_attrs_rec(
Rest@1,
begin
_pipe@1 = Acc,
gleam@dict:insert(
_pipe@1,
Attr_name,
Attr_value@1
)
end
);
_ ->
logging:log(
error,
<<"Expected end single quote for attribute name: "/utf8,
Attr_name/binary>>
),
Acc
end;
_ ->
{Attr_value@2, Rest@2} = grapheme_util:get_chars_matching_func(
S3,
<<""/utf8>>,
fun grapheme_util:is_not_whitespace/1
),
get_attrs_rec(
Rest@2,
begin
_pipe@2 = Acc,
gleam@dict:insert(
_pipe@2,
Attr_name,
Attr_value@2
)
end
)
end;
_ ->
get_attrs_rec(
S1,
begin
_pipe@3 = Acc,
gleam@dict:insert(_pipe@3, Attr_name, <<""/utf8>>)
end
)
end
end.
-spec get_attrs(binary()) -> gleam@dict:dict(binary(), binary()).
get_attrs(S) ->
get_attrs_rec(S, gleam@dict:new()).
-spec insert_section_into_child_dict(
list(pre_section:raw_tag()),
section(),
gleam@dict:dict(integer(), list(section()))
) -> gleam@dict:dict(integer(), list(section())).
insert_section_into_child_dict(Tag_stack, Doc_section, Child_dict) ->
case gleam@list:first(Tag_stack) of
{ok, Parent_tag} ->
case gleam@dict:get(Child_dict, erlang:element(3, Parent_tag)) of
{ok, Children} ->
gleam@dict:insert(
Child_dict,
erlang:element(3, Parent_tag),
[Doc_section | Children]
);
{error, _} ->
_pipe = gleam@dict:new(),
gleam@dict:insert(
_pipe,
erlang:element(3, Parent_tag),
[Doc_section]
)
end;
{error, _} ->
Child_dict
end.
-spec sort_sections(section(), section()) -> gleam@order:order().
sort_sections(Section1, Section2) ->
case Section1 of
{tag, _, _, _, Start1, _} ->
case Section2 of
{tag, _, _, _, Start2, _} ->
gleam@int:compare(Start1, Start2);
{text, _, Start2@1, _} ->
gleam@int:compare(Start1, Start2@1)
end;
{text, _, Start1@1, _} ->
case Section2 of
{tag, _, _, _, Start2@2, _} ->
gleam@int:compare(Start1@1, Start2@2);
{text, _, Start2@3, _} ->
gleam@int:compare(Start1@1, Start2@3)
end
end.
-spec get_children(gleam@dict:dict(integer(), list(section())), integer()) -> list(section()).
get_children(Child_dict, Start) ->
case gleam@dict:get(Child_dict, Start) of
{ok, Children} ->
gleam@list:sort(Children, fun sort_sections/2);
{error, _} ->
[]
end.
-spec get_sections_rec(
list(pre_section:raw_section()),
list(pre_section:raw_tag()),
list(section()),
gleam@dict:dict(integer(), list(section()))
) -> list(section()).
get_sections_rec(Sections, Tag_stack, Acc, Child_dict) ->
case gleam@list:first(Sections) of
{ok, Doc_section} ->
case Doc_section of
{raw_text_section, Text, Start, _} ->
Text_tag = {text, Text, Start, cx:dict()},
Acc@1 = case gleam@list:first(Tag_stack) of
{ok, _} ->
Acc;
{error, _} ->
[Text_tag | Acc]
end,
get_sections_rec(
gleam@list:drop(Sections, 1),
Tag_stack,
Acc@1,
insert_section_into_child_dict(
Tag_stack,
Text_tag,
Child_dict
)
);
{raw_tag_section, Tag} ->
case erlang:element(5, Tag) of
true ->
case gleam@list:first(Tag_stack) of
{ok, Opening_tag} ->
Section_tag = {tag,
erlang:element(2, Tag),
get_attrs(
erlang:element(7, Opening_tag)
),
get_children(
Child_dict,
erlang:element(3, Opening_tag)
),
erlang:element(3, Opening_tag),
cx:dict()},
Acc@2 = case begin
_pipe = gleam@list:drop(Tag_stack, 1),
gleam@list:first(_pipe)
end of
{ok, _} ->
Acc;
{error, _} ->
[Section_tag | Acc]
end,
get_sections_rec(
gleam@list:drop(Sections, 1),
gleam@list:drop(Tag_stack, 1),
Acc@2,
insert_section_into_child_dict(
gleam@list:drop(Tag_stack, 1),
Section_tag,
Child_dict
)
);
{error, _} ->
gleam@list:sort(Acc, fun sort_sections/2)
end;
false ->
case erlang:element(6, Tag) of
true ->
Section_tag@1 = {tag,
erlang:element(2, Tag),
get_attrs(erlang:element(7, Tag)),
[],
erlang:element(3, Tag),
cx:dict()},
Acc@3 = case gleam@list:first(Tag_stack) of
{ok, _} ->
Acc;
{error, _} ->
[Section_tag@1 | Acc]
end,
get_sections_rec(
gleam@list:drop(Sections, 1),
Tag_stack,
Acc@3,
insert_section_into_child_dict(
Tag_stack,
Section_tag@1,
Child_dict
)
);
false ->
get_sections_rec(
gleam@list:drop(Sections, 1),
[Tag | Tag_stack],
Acc,
Child_dict
)
end
end
end;
{error, _} ->
gleam@list:sort(Acc, fun sort_sections/2)
end.
-spec get_sections(list(pre_section:raw_section())) -> list(section()).
get_sections(Raw_sections) ->
gleam@list:sort(
get_sections_rec(Raw_sections, [], [], gleam@dict:new()),
fun sort_sections/2
).