-module(lustre@element). -compile([no_auto_import, nowarn_unused_vars]). -export([element/3, namespaced/4, text/1, map/2, to_string_builder/2, to_string/1]). -export_type([element/1]). -opaque element(FMK) :: {text, binary()} | {element, binary(), list(lustre@attribute:attribute(FMK)), list(element(FMK))} | {element_ns, binary(), list(lustre@attribute:attribute(FMK)), list(element(FMK)), binary()}. -spec element( binary(), list(lustre@attribute:attribute(FML)), list(element(FML)) ) -> element(FML). element(Tag, Attrs, Children) -> {element, Tag, Attrs, Children}. -spec namespaced( binary(), binary(), list(lustre@attribute:attribute(FMR)), list(element(FMR)) ) -> element(FMR). namespaced(Namespace, Tag, Attrs, Children) -> {element_ns, Tag, Attrs, Children, Namespace}. -spec text(binary()) -> element(any()). text(Content) -> {text, Content}. -spec escape(binary(), binary()) -> binary(). escape(Escaped, Content) -> case Content of <<"<"/utf8, Rest/binary>> -> escape(<>, Rest); <<">"/utf8, Rest@1/binary>> -> escape(<>, Rest@1); <<"&"/utf8, Rest@2/binary>> -> escape(<>, Rest@2); <<"\""/utf8, Rest@3/binary>> -> escape(<>, Rest@3); <<"'"/utf8, Rest@4/binary>> -> escape(<>, Rest@4); _ -> case gleam@string:pop_grapheme(Content) of {ok, {X, Xs}} -> escape(<>, Xs); {error, _} -> Escaped end end. -spec map(element(FMZ), fun((FMZ) -> FNB)) -> element(FNB). map(Element, F) -> case Element of {text, Content} -> {text, Content}; {element, Tag, Attrs, Children} -> {element, Tag, gleam@list:map( Attrs, fun(_capture) -> lustre@attribute:map(_capture, F) end ), gleam@list:map( Children, fun(_capture@1) -> map(_capture@1, F) end )}; {element_ns, Tag@1, Attrs@1, Children@1, Namespace} -> {element_ns, Tag@1, gleam@list:map( Attrs@1, fun(_capture@2) -> lustre@attribute:map(_capture@2, F) end ), gleam@list:map( Children@1, fun(_capture@3) -> map(_capture@3, F) end ), Namespace} end. -spec attrs_to_string_builder( gleam@string_builder:string_builder(), list(lustre@attribute:attribute(any())) ) -> gleam@string_builder:string_builder(). attrs_to_string_builder(Html, Attrs) -> gleam@list:fold(Attrs, Html, fun(Html@1, Attr) -> _pipe = Html@1, _pipe@1 = gleam@string_builder:append(_pipe, <<" "/utf8>>), gleam@string_builder:append_builder( _pipe@1, lustre@attribute:to_string_builder(Attr) ) end). -spec children_to_string_builder( gleam@string_builder:string_builder(), list(element(any())), boolean() ) -> gleam@string_builder:string_builder(). children_to_string_builder(Html, Children, Raw_text) -> gleam@list:fold( Children, Html, fun(Html@1, Child) -> gleam@string_builder:append_builder( Html@1, to_string_builder(Child, Raw_text) ) end ). -spec to_string_builder(element(any()), boolean()) -> gleam@string_builder:string_builder(). to_string_builder(Element, Raw_text) -> case Element of {text, Content} when Raw_text -> gleam@string_builder:from_string(Content); {text, Content@1} -> gleam@string_builder:from_string(escape(<<""/utf8>>, Content@1)); {element, <<"area"/utf8>> = Tag, Attrs, _} -> _pipe = gleam@string_builder:from_string(<<"<"/utf8, Tag/binary>>), _pipe@1 = attrs_to_string_builder(_pipe, Attrs), gleam@string_builder:append(_pipe@1, <<">"/utf8>>); {element, <<"base"/utf8>> = Tag, Attrs, _} -> _pipe = gleam@string_builder:from_string(<<"<"/utf8, Tag/binary>>), _pipe@1 = attrs_to_string_builder(_pipe, Attrs), gleam@string_builder:append(_pipe@1, <<">"/utf8>>); {element, <<"br"/utf8>> = Tag, Attrs, _} -> _pipe = gleam@string_builder:from_string(<<"<"/utf8, Tag/binary>>), _pipe@1 = attrs_to_string_builder(_pipe, Attrs), gleam@string_builder:append(_pipe@1, <<">"/utf8>>); {element, <<"col"/utf8>> = Tag, Attrs, _} -> _pipe = gleam@string_builder:from_string(<<"<"/utf8, Tag/binary>>), _pipe@1 = attrs_to_string_builder(_pipe, Attrs), gleam@string_builder:append(_pipe@1, <<">"/utf8>>); {element, <<"embed"/utf8>> = Tag, Attrs, _} -> _pipe = gleam@string_builder:from_string(<<"<"/utf8, Tag/binary>>), _pipe@1 = attrs_to_string_builder(_pipe, Attrs), gleam@string_builder:append(_pipe@1, <<">"/utf8>>); {element, <<"hr"/utf8>> = Tag, Attrs, _} -> _pipe = gleam@string_builder:from_string(<<"<"/utf8, Tag/binary>>), _pipe@1 = attrs_to_string_builder(_pipe, Attrs), gleam@string_builder:append(_pipe@1, <<">"/utf8>>); {element, <<"img"/utf8>> = Tag, Attrs, _} -> _pipe = gleam@string_builder:from_string(<<"<"/utf8, Tag/binary>>), _pipe@1 = attrs_to_string_builder(_pipe, Attrs), gleam@string_builder:append(_pipe@1, <<">"/utf8>>); {element, <<"input"/utf8>> = Tag, Attrs, _} -> _pipe = gleam@string_builder:from_string(<<"<"/utf8, Tag/binary>>), _pipe@1 = attrs_to_string_builder(_pipe, Attrs), gleam@string_builder:append(_pipe@1, <<">"/utf8>>); {element, <<"link"/utf8>> = Tag, Attrs, _} -> _pipe = gleam@string_builder:from_string(<<"<"/utf8, Tag/binary>>), _pipe@1 = attrs_to_string_builder(_pipe, Attrs), gleam@string_builder:append(_pipe@1, <<">"/utf8>>); {element, <<"meta"/utf8>> = Tag, Attrs, _} -> _pipe = gleam@string_builder:from_string(<<"<"/utf8, Tag/binary>>), _pipe@1 = attrs_to_string_builder(_pipe, Attrs), gleam@string_builder:append(_pipe@1, <<">"/utf8>>); {element, <<"param"/utf8>> = Tag, Attrs, _} -> _pipe = gleam@string_builder:from_string(<<"<"/utf8, Tag/binary>>), _pipe@1 = attrs_to_string_builder(_pipe, Attrs), gleam@string_builder:append(_pipe@1, <<">"/utf8>>); {element, <<"source"/utf8>> = Tag, Attrs, _} -> _pipe = gleam@string_builder:from_string(<<"<"/utf8, Tag/binary>>), _pipe@1 = attrs_to_string_builder(_pipe, Attrs), gleam@string_builder:append(_pipe@1, <<">"/utf8>>); {element, <<"track"/utf8>> = Tag, Attrs, _} -> _pipe = gleam@string_builder:from_string(<<"<"/utf8, Tag/binary>>), _pipe@1 = attrs_to_string_builder(_pipe, Attrs), gleam@string_builder:append(_pipe@1, <<">"/utf8>>); {element, <<"wbr"/utf8>> = Tag, Attrs, _} -> _pipe = gleam@string_builder:from_string(<<"<"/utf8, Tag/binary>>), _pipe@1 = attrs_to_string_builder(_pipe, Attrs), gleam@string_builder:append(_pipe@1, <<">"/utf8>>); {element, <<"style"/utf8>> = Tag@1, Attrs@1, Children} -> _pipe@2 = gleam@string_builder:from_string( <<"<"/utf8, Tag@1/binary>> ), _pipe@3 = attrs_to_string_builder(_pipe@2, Attrs@1), _pipe@4 = gleam@string_builder:append(_pipe@3, <<">"/utf8>>), _pipe@5 = children_to_string_builder(_pipe@4, Children, true), gleam@string_builder:append( _pipe@5, <<<<">/binary, ">"/utf8>> ); {element, <<"script"/utf8>> = Tag@1, Attrs@1, Children} -> _pipe@2 = gleam@string_builder:from_string( <<"<"/utf8, Tag@1/binary>> ), _pipe@3 = attrs_to_string_builder(_pipe@2, Attrs@1), _pipe@4 = gleam@string_builder:append(_pipe@3, <<">"/utf8>>), _pipe@5 = children_to_string_builder(_pipe@4, Children, true), gleam@string_builder:append( _pipe@5, <<<<">/binary, ">"/utf8>> ); {element, Tag@2, Attrs@2, Children@1} -> _pipe@6 = gleam@string_builder:from_string( <<"<"/utf8, Tag@2/binary>> ), _pipe@7 = attrs_to_string_builder(_pipe@6, Attrs@2), _pipe@8 = gleam@string_builder:append(_pipe@7, <<">"/utf8>>), _pipe@9 = children_to_string_builder(_pipe@8, Children@1, Raw_text), gleam@string_builder:append( _pipe@9, <<<<">/binary, ">"/utf8>> ); {element_ns, Tag@3, Attrs@3, Children@2, Namespace} -> _pipe@10 = gleam@string_builder:from_string( <<"<"/utf8, Tag@3/binary>> ), _pipe@11 = attrs_to_string_builder(_pipe@10, Attrs@3), _pipe@12 = gleam@string_builder:append( _pipe@11, <<<<" xmlns=\""/utf8, Namespace/binary>>/binary, "\""/utf8>> ), _pipe@13 = gleam@string_builder:append(_pipe@12, <<">"/utf8>>), _pipe@14 = children_to_string_builder( _pipe@13, Children@2, Raw_text ), gleam@string_builder:append( _pipe@14, <<<<">/binary, ">"/utf8>> ) end. -spec to_string(element(any())) -> binary(). to_string(Element) -> _pipe = to_string_builder(Element, false), gleam@string_builder:to_string(_pipe).