anchor.diff:      [] ->
         {IStack, [], State2};
       _ ->
  -      LineTokens2 = [{newline, get(line_num)} | LineTokens],
  +      LineTokens2 = [{newline, ?LN} | LineTokens],
         {IStack2, LineTokens3} = process_dents(Dents, IStack, LineTokens2),
         {IStack2, LineTokens3, State2}
     end.
  
positive.code: -module(zss_tokenizer).
  
  -export([tokenize_str/1, tokenize_file/1, tokenize_stream/1]).
  
  tokenize_str(InStr) ->
    erase(),
  
negative.code:   {[], TokenAcc};
  do_dedent(Dents, [H | _] = IStack, TokenAcc) when Dents > H ->
    erlang:error({strange_indentation,
        {line, ?LN},
        {curr_dents, Dents},
        {ind_stack, IStack},
        {token_acc, TokenAcc}});
  do_dedent(Dents, [H | _] = IStack, TokenAcc) when Dents == H ->
    {IStack, TokenAcc};
  do_dedent(Dents, [H | T], TokenAcc) when Dents < H ->
    do_dedent(Dents, T, [{dedent, ?LN} | TokenAcc]).
  
  
  line_tokens(Line, State) ->
    line_tokens(Line, none, [], [], State).
    %{[{general, Line}], State}.
  
  % Line is finished- move current-token to all, and return
  line_tokens([], _, CurrTAcc, AllTAcc, State) ->
    {?SFLUSH, State};
  
  % Escaped character.  Pops the escape char off current token, adds this
  % character to the token no matter what it is, and sends 'none' as last token
  % so that double-character tokens like |# can be escaped.
  line_tokens([Any | T], ?T_ESC, [?T_ESC | CurrTAcc], AllTAcc, State) ->
    line_tokens(T, none, [Any | CurrTAcc], AllTAcc, State);
  
  % String
  line_tokens([?T_STR_MLT_ST_2 | T], ?T_STR_MLT_ST_1,
  [_ | CurrTAcc], AllTAcc, State) ->
    {Str, Remaining} = pull_inner(T, fun line_pull_in_str/1),
    line_tokens(Remaining, string, [], ?FLUSH({string, ?LN, Str}), State);
  
  % Whitespace.  Flush token.
  line_tokens([H | T], _Last, CurrTAcc, AllTAcc, State) when
      ((H >= $\x{0009}) and (H =< $\x{000D}))
      or (H == $\x{0020}) or (H == $\x{00A0}) ->
    line_tokens(T, H, [], ?SFLUSH, State);
  
  line_tokens([H | T], _Last, CurrTAcc, AllTAcc, State) ->
    line_tokens(T, H, [H | CurrTAcc], AllTAcc, State).
  
  
  pull_inner(Line, InnerFun) ->
    pull_inner(Line, [], ?LN, InnerFun).
  pull_inner(Line, Acc, LN, InnerFun) ->
    {StrAcc, Finished, Tail} = InnerFun(Line),
    case Finished of
      true ->
        put(line_num, LN),
        {lists:flatten(lists:reverse([StrAcc | Acc])), Tail};
      false ->
        Next = get(next_fun),
        case Next() of
          eof ->
            erlang:error({string_or_comment_not_closed_before_eof,
                {line, ?LN}});
          {error, Reason} ->
            erlang:error({input_zss_read_error, Reason});
          NewLine ->
            pull_inner(NewLine, [StrAcc | Acc], LN + 1, InnerFun)
        end
    end.
  
  line_pull_in_str(Line) ->
    line_pull_in_str(Line, none, []).
  line_pull_in_str([Any | T], ?T_ESC, [?T_ESC | Acc]) ->
    line_pull_in_str(T, nothing, [Any | Acc]);
  line_pull_in_str([?T_STR_MLT_EN_2 | T], ?T_STR_MLT_EN_1, [_ | Acc]) ->
    {lists:reverse(Acc), true, T};
  line_pull_in_str([], _, Acc) ->
    {lists:reverse(Acc), false, []};
  line_pull_in_str([H | T], _, Acc) ->
    line_pull_in_str(T, H, [H | Acc]).
  
  