anchor.diff:  
   %% @doc Update delimiter part of the `parse/1'
   %%
  -%% NewDelimiterBin :: e.g. `{{=%% %%=}}' -> `%% %%'
  --spec parse_delimiter(state(), NewDelimiterBin :: binary(), NextBin :: binary(), Result :: [tag()]) -> [tag()] | partial().
  -parse_delimiter(State0, NewDelimiterBin, NextBin, Result) ->
  -    case binary:match(NewDelimiterBin, <<"=">>) of
  +%% Parse_StringDelimiterBin :: e.g. `{{=%% %%=}}' -> `%% %%'
  +-spec parse_delimiter(state(), Parse_StringDelimiterBin :: binary(), NextBin :: binary(), Result :: [tag()]) -> [tag()] | partial().
  +parse_delimiter(State0, Parse_StringDelimiterBin, NextBin, Result) ->
  +    case binary:match(Parse_StringDelimiterBin, <<"=">>) of
           nomatch ->
  -            case [X || X <- binary:split(NewDelimiterBin, <<" ">>, [global]), X =/= <<>>] of
  +            case [X || X <- binary:split(Parse_StringDelimiterBin, <<" ">>, [global]), X =/= <<>>] of
                   [Start, Stop] -> parse1(State0#state{start = Start, stop = Stop}, NextBin, Result);
                   _             -> error(?PARSE_ERROR)
               end;
  
positive.code: 
       {"{{#tag}}",    ?NT_F(<<"{{#tag}}">>)},
       {"{{#tag1}}{{#tag2}}{{name}}{{/tag1}}{{/tag2}}",
        ?NT_S([<<"a">>, {'#', <<"t1">>, [<<"b">>, {'#', <<"t2">>, [<<"c">>, {n, <<"t3">>}, <<"d">>]}, <<"e">>]}, <<"f">>],
              <<"a{{#t1}}b{{#t2}}c{{t3}}d{{/t2}}e{{/t1}}f">>)},
       {"{{#tag1}}{{#tag2}}{{/tag1}}{{/tag2}}", ?NT_F(<<"{{#t1}}{{#t2}}{{/t1}}{{/t2}}">>)},
  
       {"{{# tag}}{{/ tag}}",     ?NT_S([<<>>, {'#', <<"tag">>, [<<>>]}, <<>>],  <<"{{# tag}}{{/ tag}}">>)},
       {"{{ #tag }}{{ / tag }}",  ?NT_S([<<>>, {'#', <<"tag">>, [<<>>]}, <<>>],  <<"{{ #tag }}{{ / tag }}">>)},
       {"{{ # tag }}{{ /tag }}",  ?NT_S([<<>>, {'#', <<"tag">>, [<<>>]}, <<>>],  <<"{{ # tag }}{{ /tag }}">>)},
       {"{{ # ta g}}{{ / ta g}}", ?NT_S([<<>>, {'#', <<"ta g">>, [<<>>]}, <<>>], <<"{{ # ta g}}{{ / ta g}}">>)},
  
       {"{{!comment}}",           ?NT_S([<<"a">>, <<"c">>], <<"a{{!comment}}c">>)},
       {"{{! comment }}",         ?NT_S([<<>>, <<>>],       <<"{{! comment }}">>)},
  
negative.code:         }).
  
  -opaque template() :: #?MODULE{}.
  -type data()       :: #{string() => data() | iodata() | fun((data(), function()) -> iodata())}.
  -type partial()    :: {partial, {state(), EndTag :: binary(), LastTagSize :: non_neg_integer(), Rest :: binary(), [tag()]}}.
  
  %%----------------------------------------------------------------------------------------------------------------------
  %% Exported Functions
  %%----------------------------------------------------------------------------------------------------------------------
  
  %% @doc
  -spec render(binary(), data()) -> binary().
  render(Bin, Map) ->
      compile(parse_string(Bin), Map).
  
  %% @doc
  -spec parse_string(binary()) -> template().
  parse_string(Bin) when is_binary(Bin) ->
      parse_string_impl(#state{}, Bin).
  
  %% @doc
  -spec parse_file(file:filename()) -> template().
  parse_file(Filename) ->
      case file:read_file(Filename) of
          {ok, Bin} -> parse_string_impl(#state{dirname = filename:dirname(Filename)}, Bin);
          _         -> error(?FILE_ERROR, [Filename])
      end.
  
  %% @doc
  -spec compile(template(), data()) -> binary().
  compile(#?MODULE{data = Tags}, Map) when is_map(Map) ->
      iolist_to_binary(lists:reverse(compile_impl(Tags, Map, []))).
  
  %%----------------------------------------------------------------------------------------------------------------------
  %% Internal Function
  %%----------------------------------------------------------------------------------------------------------------------
  
  %% @see compile/2
  %%
  %% ATTENTION: The result is a list that is inverted.
  -spec compile_impl(Template :: [tag()], data(), Result :: iodata()) -> iodata().
  compile_impl([], _, Result) ->
      Result;
  compile_impl([{n, Key} | T], Map, Result) ->
      compile_impl(T, Map, [escape(maps:get(Key, Map)) | Result]);
  compile_impl([{'&', Key} | T], Map, Result) ->
      compile_impl(T, Map, [maps:get(Key, Map) | Result]);
  compile_impl([{'#', Key, Tags, Source} | T], Map, Result) ->
      Value = maps:get(Key, Map, undefined),
      if
          is_list(Value)        -> compile_impl(T, Map, lists:foldl(fun(X, Acc) -> compile_impl(Tags, X, Acc) end,
                                                                    Result, Value));
          Value =:= false       -> compile_impl(T, Map, Result);
          is_function(Value, 2) -> compile_impl(T, Map, Value(Source, fun(Text) -> render(Text, Map) end));
          true                  -> compile_impl(T, Map, compile_impl(Tags, Map, Result))
      end;
  compile_impl([{'^', Key, Tags} | T], Map, Result) ->
      Value = maps:get(Key, Map, undefined),
      case Value =:= undefined orelse Value =:= [] orelse Value =:= false of
          true  -> compile_impl(T, Map, compile_impl(Tags, Map, Result));
          false -> compile_impl(T, Map, Result)
      end;
  compile_impl([Bin | T], Map, Result) ->
      compile_impl(T, Map, [Bin | Result]).
  
  %% @see parse_string/1
  -spec parse_string_impl(state(), Input :: binary()) -> template().
  parse_string_impl(State, Input) ->
      #?MODULE{data = parse(State, Input)}.
  
  %% @doc
  