anchor.diff:  to_html([{end_tag, Tag} | Rest], Acc) ->
       to_html(Rest, [["</" ++ Tag, ">"] | Acc]).
   
  +doctype_to_html([], Acc) ->
  +    lists:reverse(Acc);
  +doctype_to_html([Word | Rest], Acc) ->
  +    case lists:all(fun (C) -> ?IS_LITERAL_SAFE(C) end, Word) of
  +        true ->
  +            doctype_to_html(Rest, [" " ++ Word | Acc]);
  +        false ->
  +            doctype_to_html(Rest, [[" \"" ++ escape_attr(Word), ?QUOTE] | Acc])
  +    end.
  +
   attrs_to_html([], Acc) ->
       lists:reverse(Acc);
   attrs_to_html([{K, V} | Rest], Acc) ->
  
positive.code: %% Internal API
  
  test_to_html() ->
      Expect = <<"<html><head><title>hey!</title></head><body><p class=\"foo\">what's up<br /></p><div>sucka</div></body></html>">>,
      Expect = iolist_to_binary(
                 to_html({html, [],
                          [{"head",
                            [{title, "hey!"}]},
                           {body, [],
                            [{p, [{class, foo}], ["what's", <<" up">>, {br}]},
                             {'div', <<"sucka">>}]}]})),
      ok.
  to_html([], Acc) ->
      lists:reverse(Acc);
  to_html([{data, Data, _Whitespace} | Rest], Acc) ->
      to_html(Rest, [escape(Data) | Acc]);
  to_html([{start_tag, Tag, Attrs, Singleton} | Rest], Acc) ->
  
negative.code:                       [{start_tag, T1, A1, false} | Acc])
      end;
  to_tokens([{Tag0, [L | R1]} | Rest], Acc) when is_list(L) ->
      %% List text
      Tag = to_tag(Tag0),
      to_tokens([{Tag, R1} | Rest], [{data, L, false} | Acc]);
  to_tokens([{Tag0, [B | R1]} | Rest], Acc) when is_binary(B) ->
      %% Binary text
      Tag = to_tag(Tag0),
      to_tokens([{Tag, R1} | Rest], [{data, binary_to_list(B), false} | Acc]).
  
  