Current section
Files
Jump to
Current section
Files
src/htmz@selector_parser.erl
-module(htmz@selector_parser).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([parse_css_selector/1]).
-export_type([parse_result/0, symbol_type/0, parse_acc/0]).
-type parse_result() :: {parse_result, binary(), list({binary(), binary()})}.
-type symbol_type() :: tag | class | id | attribute_name | attribute_value.
-type parse_acc() :: {parse_acc,
binary(),
list({binary(), binary()}),
binary(),
binary(),
symbol_type(),
list(binary())}.
-spec find_class_in_attrs(list({binary(), binary()})) -> binary().
find_class_in_attrs(Attrs) ->
Class_attr = begin
_pipe = Attrs,
_pipe@1 = gleam@list:find(_pipe, fun(Attr) -> case Attr of
{<<"class"/utf8>>, _} ->
true;
_ ->
false
end end),
gleam@result:unwrap(_pipe@1, {<<""/utf8>>, <<""/utf8>>})
end,
case Class_attr of
{<<"class"/utf8>>, Cls} ->
Cls;
_ ->
<<""/utf8>>
end.
-spec tag_name(binary()) -> binary().
tag_name(Word) ->
case Word of
<<""/utf8>> ->
<<"div"/utf8>>;
_ ->
Word
end.
-spec finish_prefix(parse_acc()) -> gleam@option:option(parse_acc()).
finish_prefix(Acc) ->
case erlang:element(6, Acc) of
tag ->
Tag = case erlang:element(2, Acc) of
<<""/utf8>> ->
tag_name(erlang:element(4, Acc));
_ ->
erlang:element(2, Acc)
end,
{some,
erlang:setelement(
4,
erlang:setelement(2, Acc, Tag),
<<""/utf8>>
)};
id ->
{some,
erlang:setelement(
4,
erlang:setelement(
3,
Acc,
[{<<"id"/utf8>>, erlang:element(4, Acc)} |
erlang:element(3, Acc)]
),
<<""/utf8>>
)};
class ->
case erlang:element(4, Acc) of
<<""/utf8>> ->
gleam@io:debug({<<"failed2"/utf8>>, Acc}),
none;
_ ->
{some,
erlang:setelement(
4,
erlang:setelement(
7,
Acc,
[erlang:element(4, Acc) |
erlang:element(7, Acc)]
),
<<""/utf8>>
)}
end;
attribute_name ->
case erlang:element(2, Acc) of
<<""/utf8>> ->
gleam@io:debug({<<"failed3"/utf8>>, Acc}),
none;
_ ->
{some, Acc}
end;
attribute_value ->
case erlang:element(4, Acc) of
<<""/utf8>> ->
gleam@io:debug({<<"failed4"/utf8>>, Acc}),
none;
_ ->
{some,
erlang:setelement(
4,
erlang:setelement(
5,
erlang:setelement(
3,
Acc,
[{erlang:element(5, Acc),
erlang:element(4, Acc)} |
erlang:element(3, Acc)]
),
<<""/utf8>>
),
<<""/utf8>>
)}
end
end.
-spec process_char(parse_acc(), binary()) -> gleam@option:option(parse_acc()).
process_char(Acc, Char) ->
case Char of
<<"#"/utf8>> ->
case erlang:element(6, Acc) of
tag ->
{some,
erlang:setelement(
6,
erlang:setelement(
4,
erlang:setelement(
2,
Acc,
tag_name(erlang:element(4, Acc))
),
<<""/utf8>>
),
id
)};
class ->
Classes = [erlang:element(4, Acc) | erlang:element(7, Acc)],
{some,
erlang:setelement(
4,
erlang:setelement(
6,
erlang:setelement(7, Acc, Classes),
id
),
<<""/utf8>>
)};
_ ->
gleam@io:debug({<<"failed1"/utf8>>, Acc}),
none
end;
<<"."/utf8>> ->
gleam@option:map(
finish_prefix(Acc),
fun(Acc@1) -> erlang:setelement(6, Acc@1, class) end
);
<<"["/utf8>> ->
gleam@option:map(
finish_prefix(Acc),
fun(Acc@2) -> erlang:setelement(6, Acc@2, attribute_name) end
);
<<"="/utf8>> ->
gleam@option:map(
finish_prefix(Acc),
fun(Acc@3) -> erlang:setelement(6, Acc@3, attribute_value) end
);
<<"]"/utf8>> ->
gleam@option:map(
finish_prefix(Acc),
fun(Acc@4) -> erlang:setelement(6, Acc@4, tag) end
);
_ ->
case erlang:element(6, Acc) of
attribute_name ->
{some,
erlang:setelement(
5,
Acc,
<<(erlang:element(5, Acc))/binary, Char/binary>>
)};
_ ->
{some,
erlang:setelement(
4,
Acc,
<<(erlang:element(4, Acc))/binary, Char/binary>>
)}
end
end.
-spec parse_css_selector(binary()) -> gleam@option:option(parse_result()).
parse_css_selector(Css_selector) ->
Acc@2 = begin
_pipe = gleam@string:to_graphemes(Css_selector),
_pipe@1 = gleam@iterator:from_list(_pipe),
gleam@iterator:fold(
_pipe@1,
{some,
{parse_acc, <<""/utf8>>, [], <<""/utf8>>, <<""/utf8>>, tag, []}},
fun(Acc, Char) -> case Acc of
none ->
none;
{some, Acc@1} ->
process_char(Acc@1, Char)
end end
)
end,
case Acc@2 of
none ->
none;
{some, Acc@3} ->
Acc@4 = finish_prefix(Acc@3),
gleam@option:map(
Acc@4,
fun(Acc@5) ->
Attrs = case gleam@list:is_empty(erlang:element(7, Acc@5)) of
true ->
erlang:element(3, Acc@5);
false ->
Class_in_attr = case find_class_in_attrs(
erlang:element(3, Acc@5)
) of
<<""/utf8>> ->
<<""/utf8>>;
Cls ->
<<Cls/binary, " "/utf8>>
end,
Cls@1 = <<Class_in_attr/binary,
(begin
_pipe@2 = erlang:element(7, Acc@5),
_pipe@3 = gleam@list:unique(_pipe@2),
_pipe@4 = gleam@list:reverse(_pipe@3),
gleam@string:join(_pipe@4, <<" "/utf8>>)
end)/binary>>,
[{<<"class"/utf8>>, Cls@1} |
begin
_pipe@5 = erlang:element(3, Acc@5),
gleam@list:reverse(_pipe@5)
end]
end,
{parse_result, tag_name(erlang:element(2, Acc@5)), Attrs}
end
)
end.