-module(pre_section). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([get_raw_sections/2]). -export_type([raw_tag/0, raw_section/0]). -type raw_tag() :: {raw_tag, binary(), integer(), integer(), boolean(), boolean(), binary()}. -type raw_section() :: {raw_text_section, binary(), integer(), integer()} | {raw_tag_section, raw_tag()}. -spec get_attrs_text(binary()) -> {binary(), binary()}. get_attrs_text(S) -> grapheme_util:get_chars_matching_func( S, <<""/utf8>>, fun grapheme_util:is_not_gt/1 ). -spec get_tags_rec( binary(), integer(), gleam@set:set(binary()), list(raw_tag()) ) -> {ok, list(raw_tag())} | {error, tagg_error:tagg_error()}. get_tags_rec(S, I, Custom_tag_names, Acc) -> case S of <<"> -> get_tags_rec(Rest, I + 2, Custom_tag_names, Acc); <<"> -> Start = I, I@1 = I + 2, {Tag_name, Rest@2, Num_graphemes} = grapheme_util:get_name_ignore_ws( Rest@1 ), I@2 = I@1 + Num_graphemes, case gleam@set:contains(Custom_tag_names, Tag_name) of true -> case Rest@2 of <<">"/utf8, Rest@3/binary>> -> get_tags_rec( Rest@3, I@2 + 1, Custom_tag_names, [{raw_tag, Tag_name, Start, I@2, true, false, <<""/utf8>>} | Acc] ); _ -> {error, {tag_not_closed_error, <<"Closing tag not closed for tag: "/utf8, Tag_name/binary>>}} end; false -> get_tags_rec(Rest@2, I@2, Custom_tag_names, Acc) end; <<"<"/utf8, Rest@4/binary>> -> Start@1 = I, I@3 = I + 1, {Tag_name@1, Rest@5, Num_graphemes@1} = grapheme_util:get_name_ignore_ws( Rest@4 ), I@4 = I@3 + Num_graphemes@1, case gleam@set:contains(Custom_tag_names, Tag_name@1) of true -> {Attrs_text, Rest@6} = get_attrs_text(Rest@5), I@5 = I@4 + gleam@string:length(Attrs_text), case Rest@6 of <<">"/utf8, Rest@7/binary>> -> case gleam@string:ends_with( Attrs_text, <<"/"/utf8>> ) of true -> get_tags_rec( Rest@7, I@5 + 1, Custom_tag_names, [{raw_tag, Tag_name@1, Start@1, I@5, false, true, gleam@string:drop_right( Attrs_text, 1 )} | Acc] ); false -> get_tags_rec( Rest@7, I@5 + 1, Custom_tag_names, [{raw_tag, Tag_name@1, Start@1, I@5, false, false, Attrs_text} | Acc] ) end; _ -> {error, {tag_not_closed_error, <<"Closing tag not closed for tag: "/utf8, Tag_name@1/binary>>}} end; false -> get_tags_rec(Rest@5, I@4, Custom_tag_names, Acc) end; _ -> case gleam@string:pop_grapheme(S) of {ok, {_, Rest@8}} -> get_tags_rec(Rest@8, I + 1, Custom_tag_names, Acc); {error, _} -> {ok, Acc} end end. -spec get_tags(binary(), gleam@set:set(binary())) -> {ok, list(raw_tag())} | {error, tagg_error:tagg_error()}. get_tags(S, Custom_tag_names) -> case get_tags_rec(S, 0, Custom_tag_names, []) of {ok, Tags} -> {ok, lists:reverse(Tags)}; {error, Err} -> {error, Err} end. -spec get_raw_sections_rec( list(raw_tag()), binary(), integer(), list(raw_section()) ) -> list(raw_section()). get_raw_sections_rec(Tags, S, I, Acc) -> case gleam@list:first(Tags) of {ok, Tag} -> case I < erlang:element(3, Tag) of true -> Text_len = erlang:element(3, Tag) - I, Tag_len = (erlang:element(4, Tag) - erlang:element(3, Tag)) + 1, get_raw_sections_rec( gleam@list:drop(Tags, 1), gleam@string:drop_left(S, Text_len + Tag_len), erlang:element(4, Tag) + 1, [{raw_tag_section, Tag}, {raw_text_section, gleam@string:slice(S, 0, Text_len), I, erlang:element(3, Tag) - 1} | Acc] ); false -> get_raw_sections_rec( gleam@list:drop(Tags, 1), gleam@string:drop_left( S, (erlang:element(4, Tag) - erlang:element(3, Tag)) + 1 ), erlang:element(4, Tag) + 1, [{raw_tag_section, Tag} | Acc] ) end; {error, _} -> case gleam@string:is_empty(S) of true -> Acc; false -> [{raw_text_section, S, I, (I + gleam@string:length(S)) - 1} | Acc] end end. -spec get_raw_sections(binary(), gleam@set:set(binary())) -> {ok, list(raw_section())} | {error, tagg_error:tagg_error()}. get_raw_sections(S, Custom_tag_names) -> case get_tags(S, Custom_tag_names) of {ok, Tags} -> {ok, lists:reverse( begin _pipe = Tags, get_raw_sections_rec(_pipe, S, 0, []) end )}; {error, Err} -> {error, Err} end.