-module(gtemplate). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -define(FILEPATH, "src/gtemplate.gleam"). -export([get_block/2, tokenize/2, create_template/1, create_template_from_block/2, create_template_from_file/2, render_template/2]). -export_type([token/0, template/0, variable/0]). -opaque token() :: {text, binary()} | {variable, binary()} | {loop, binary(), binary(), list(token())} | {'if', binary(), list(token()), list(token())}. -opaque template() :: {template, list(token())}. -type variable() :: {string, binary()} | {list, list(variable())} | {bool, boolean()}. -file("src/gtemplate.gleam", 53). -spec get_block(binary(), binary()) -> {ok, binary()} | {error, nil}. get_block(Str, Name) -> gleam@result:'try'( begin _pipe = Str, gleam@string:split_once( _pipe, <<<<"{{{ block "/utf8, Name/binary>>/binary, " }}}"/utf8>> ) end, fun(_use0) -> {_, Str@1} = _use0, gleam@result:'try'( begin _pipe@1 = Str@1, gleam@string:split_once( _pipe@1, <<"{{{ end block }}}"/utf8>> ) end, fun(_use0@1) -> {Str@2, _} = _use0@1, _pipe@2 = Str@2, {ok, _pipe@2} end ) end ). -file("src/gtemplate.gleam", 61). -spec tokenize(binary(), list(token())) -> {ok, list(token())} | {error, binary()}. tokenize(Str, Acc) -> case begin _pipe = Str, gleam@string:split_once(_pipe, <<"{{ "/utf8>>) end of {ok, {Before, After}} -> Result = begin _pipe@1 = After, gleam@string:split_once(_pipe@1, <<" }}"/utf8>>) end, Result@1 = case Result of {ok, X} -> _pipe@2 = X, {ok, _pipe@2}; {error, _} -> {error, <<"Unfinished instruction"/utf8>>} end, gleam@result:'try'( Result@1, fun(_use0) -> {Token, After@1} = _use0, Token@1 = begin _pipe@3 = Token, gleam@string:split(_pipe@3, <<" "/utf8>>) end, Token@4 = case Token@1 of [<<"loop"/utf8>>, Iterable, <<"as"/utf8>>, Variable_name] -> End_loop = case begin _pipe@4 = After@1, _pipe@5 = gleam@string:split( _pipe@4, <<"{{ end loop }}"/utf8>> ), lists:reverse(_pipe@5) end of [_] -> {error, <<<<<<<<"loop "/utf8, Iterable/binary>>/binary, " as "/utf8>>/binary, Variable_name/binary>>/binary, " has no end loop"/utf8>>}; [] -> erlang:error(#{gleam_error => panic, message => <<"`panic` expression evaluated."/utf8>>, file => <>, module => <<"gtemplate"/utf8>>, function => <<"tokenize"/utf8>>, line => 87}); [After@2 | Inner] -> Inner@1 = begin _pipe@6 = Inner, _pipe@7 = lists:reverse(_pipe@6), gleam@string:join( _pipe@7, <<"{{ end loop }}"/utf8>> ) end, {ok, {Inner@1, After@2}} end, gleam@result:'try'( End_loop, fun(_use0@1) -> {Inner@2, After@3} = _use0@1, gleam@result:'try'( tokenize(Inner@2, []), fun(Inner@3) -> Loop = {loop, Iterable, Variable_name, Inner@3}, _pipe@8 = {Loop, After@3}, {ok, _pipe@8} end ) end ); [<<"if"/utf8>>, Condition, <<"then"/utf8>>] -> End_if = case begin _pipe@9 = After@1, _pipe@10 = gleam@string:split( _pipe@9, <<"{{ end if }}"/utf8>> ), lists:reverse(_pipe@10) end of [_] -> {error, <<<<<<"if "/utf8, Condition/binary>>/binary, " then"/utf8>>/binary, " has no end if"/utf8>>}; [] -> erlang:error(#{gleam_error => panic, message => <<"`panic` expression evaluated."/utf8>>, file => <>, module => <<"gtemplate"/utf8>>, function => <<"tokenize"/utf8>>, line => 105}); [After@4 | Inner@4] -> Inner@5 = begin _pipe@11 = Inner@4, _pipe@12 = lists:reverse(_pipe@11), gleam@string:join( _pipe@12, <<"{{ end if }}"/utf8>> ) end, {ok, {Inner@5, After@4}} end, gleam@result:'try'( End_if, fun(_use0@2) -> {Inner@6, After@5} = _use0@2, Token@2 = case begin _pipe@13 = Inner@6, _pipe@14 = gleam@string:split( _pipe@13, <<"{{ else }}"/utf8>> ), lists:reverse(_pipe@14) end of [Str@1] -> gleam@result:'try'( begin _pipe@15 = Str@1, tokenize(_pipe@15, []) end, fun(Then_tokens) -> {ok, {'if', Condition, Then_tokens, []}} end ); [Else_tokens | Then_tokens@1] -> Then_tokens@2 = begin _pipe@16 = Then_tokens@1, _pipe@17 = lists:reverse( _pipe@16 ), gleam@string:join( _pipe@17, <<"{{ else }}"/utf8>> ) end, gleam@result:'try'( tokenize(Then_tokens@2, []), fun(Then_tokens@3) -> gleam@result:'try'( tokenize( Else_tokens, [] ), fun(Else_tokens@1) -> {ok, {'if', Condition, Then_tokens@3, Else_tokens@1}} end ) end ); _ -> erlang:error(#{gleam_error => panic, message => <<"`panic` expression evaluated."/utf8>>, file => <>, module => <<"gtemplate"/utf8>>, function => <<"tokenize"/utf8>>, line => 124}) end, gleam@result:'try'( Token@2, fun(Token@3) -> {ok, {Token@3, After@5}} end ) end ); [Var] -> _pipe@18 = {{variable, Var}, After@1}, {ok, _pipe@18}; _ -> {error, <<"Empty instruction"/utf8>>} end, gleam@result:'try'( Token@4, fun(_use0@3) -> {Token@5, After@6} = _use0@3, Before@1 = {text, Before}, Acc@1 = lists:append(Acc, [Before@1, Token@5]), tokenize(After@6, Acc@1) end ) end ); {error, _} -> _pipe@19 = lists:append(Acc, [{text, Str}]), {ok, _pipe@19} end. -file("src/gtemplate.gleam", 45). -spec create_template(binary()) -> {ok, template()} | {error, binary()}. create_template(Str) -> Tokens = begin _pipe = Str, tokenize(_pipe, []) end, gleam@result:'try'(Tokens, fun(Tokens@1) -> _pipe@1 = {template, Tokens@1}, {ok, _pipe@1} end). -file("src/gtemplate.gleam", 35). -spec create_template_from_block(binary(), binary()) -> {ok, template()} | {error, binary()}. create_template_from_block(Str, Name) -> Block = get_block(Str, Name), Block@2 = case Block of {ok, Block@1} -> {ok, Block@1}; {error, _} -> {error, <<<<"Block "/utf8, Name/binary>>/binary, " does not exist"/utf8>>} end, gleam@result:'try'(Block@2, fun(Block@3) -> create_template(Block@3) end). -file("src/gtemplate.gleam", 24). -spec create_template_from_file(binary(), binary()) -> {ok, template()} | {error, binary()}. create_template_from_file(File_name, Name) -> Str = simplifile:read(File_name), Str@2 = case Str of {ok, Str@1} -> _pipe = Str@1, {ok, _pipe}; {error, Err} -> {error, <<"Error reading file: "/utf8, (simplifile:describe_error(Err))/binary>>} end, gleam@result:'try'( Str@2, fun(Str@3) -> create_template_from_block(Str@3, Name) end ). -file("src/gtemplate.gleam", 213). -spec render_loop( list(variable()), binary(), gleam@dict:dict(binary(), variable()), list(token()), binary() ) -> {ok, binary()} | {error, binary()}. render_loop(Iterable, Variable_name, Variables, Tokens, Acc) -> case Iterable of [] -> _pipe = Acc, {ok, _pipe}; [Value | Rest] -> New_variables = begin _pipe@1 = Variables, gleam@dict:insert(_pipe@1, Variable_name, Value) end, Rendered = render_tokens(Tokens, New_variables, <<""/utf8>>), gleam@result:'try'( Rendered, fun(Rendered@1) -> render_loop( Rest, Variable_name, Variables, Tokens, <> ) end ) end. -file("src/gtemplate.gleam", 155). -spec render_tokens( list(token()), gleam@dict:dict(binary(), variable()), binary() ) -> {ok, binary()} | {error, binary()}. render_tokens(Tokens, Variables, Acc) -> case Tokens of [{variable, Name} | Rest] -> Value = begin _pipe = Variables, gleam_stdlib:map_get(_pipe, Name) end, Value@2 = case Value of {ok, Value@1} -> _pipe@1 = Value@1, {ok, _pipe@1}; {error, _} -> {error, <>} end, gleam@result:'try'(Value@2, fun(Value@3) -> case Value@3 of {string, Value@4} -> render_tokens( Rest, Variables, <> ); _ -> {error, <<<<"Expected value of "/utf8, Name/binary>>/binary, " to be a string"/utf8>>} end end); [{text, Text} | Rest@1] -> render_tokens(Rest@1, Variables, <>); [{loop, Iterable, Variable_name, Inner} | Rest@2] -> Value@5 = begin _pipe@2 = Variables, gleam_stdlib:map_get(_pipe@2, Iterable) end, Value@7 = case Value@5 of {ok, Value@6} -> _pipe@3 = Value@6, {ok, _pipe@3}; {error, _} -> {error, <>} end, gleam@result:'try'( Value@7, fun(Value@8) -> Value@10 = case Value@8 of {list, Value@9} -> {ok, Value@9}; _ -> {error, <<<<"Expected value of "/utf8, Iterable/binary>>/binary, " to be a list"/utf8>>} end, gleam@result:'try'( Value@10, fun(Value@11) -> Value@12 = render_loop( Value@11, Variable_name, Variables, Inner, <<""/utf8>> ), gleam@result:'try'( Value@12, fun(Value@13) -> render_tokens( Rest@2, Variables, <> ) end ) end ) end ); [{'if', Condition, Then_tokens, Else_tokens} | Rest@3] -> Value@14 = begin _pipe@4 = Variables, gleam_stdlib:map_get(_pipe@4, Condition) end, Value@16 = case Value@14 of {ok, Value@15} -> _pipe@5 = Value@15, {ok, _pipe@5}; {error, _} -> {error, <>} end, gleam@result:'try'( Value@16, fun(Value@17) -> Value@19 = case Value@17 of {bool, Value@18} -> {ok, Value@18}; _ -> {error, <<<<"Expected value of "/utf8, Condition/binary>>/binary, " to be a bool"/utf8>>} end, gleam@result:'try'( Value@19, fun(Value@20) -> Value@21 = case Value@20 of true -> render_tokens( Then_tokens, Variables, <<""/utf8>> ); false -> render_tokens( Else_tokens, Variables, <<""/utf8>> ) end, gleam@result:'try'( Value@21, fun(Value@22) -> render_tokens( Rest@3, Variables, <> ) end ) end ) end ); [] -> _pipe@6 = Acc, {ok, _pipe@6} end. -file("src/gtemplate.gleam", 147). -spec render_template(template(), gleam@dict:dict(binary(), variable())) -> {ok, binary()} | {error, binary()}. render_template(Template, Variables) -> {template, Tokens} = Template, render_tokens(Tokens, Variables, <<""/utf8>>).