anchor.diff:      test_parse_tokens(),
       test_escape(),
       test_escape_attr(),
  +    test_to_html(),
       ok.
   
   
   %% 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) ->
  -    Open = "<" ++ Tag ++ attrs_to_html(Attrs, []) ++ case Singleton of
  -                                                         true -> " />";
  -                                                         false -> ">"
  -                                                     end,
  +    Open = ["<" ++ Tag,
  +            attrs_to_html(Attrs, []),
  +            case Singleton of
  +                true -> " />";
  +                false -> ">"
  +            end],
       to_html(Rest, [Open | Acc]);
   to_html([{end_tag, Tag} | Rest], Acc) ->
  -    to_html(Rest, ["</" ++ Tag ++ ">" | Acc]).
  +    to_html(Rest, [["</" ++ Tag, ">"] | Acc]).
   
   attrs_to_html([], Acc) ->
       lists:reverse(Acc);
   attrs_to_html([{K, V} | Rest], Acc) ->
  -    attrs_to_html(Rest, [" " ++ K ++ "=\"" ++ escape_attr(V) ++ "\"" | Acc]).
  +    attrs_to_html(Rest,
  +                  [[" " ++ escape(K), "=\"" ++ escape_attr(V), "\""] | Acc]).
       
   test_escape() ->
       "&amp;quot;\"word &lt;&lt;up!&amp;quot;" =
  
positive.code: escape_attr([C | Rest], Acc) ->
      escape_attr(Rest, [C | Acc]).
  
  to_tokens([], Acc) ->
      lists:reverse(Acc);
  to_tokens([{Tag, []} | Rest], Acc) ->
      to_tokens(Rest, [{end_tag, Tag} | Acc]);
  to_tokens([{Tag, [{T1, A1, C1} | R1]} | Rest], Acc) ->
      case is_singleton(T1) of
          true ->
              to_tokens([{Tag, R1} | Rest], [{start_tag, T1, A1, true} | Acc]);
  
negative.code:             to_tokens([{T1, C1}, {Tag, R1} | Rest],
                        [{start_tag, T1, A1, false} | Acc])
      end;
  to_tokens([{Tag0, [L | R1]} | Rest], Acc) when is_list(L) ->
      Tag = to_tag(Tag0),
      to_tokens([{Tag, R1} | Rest], [{data, L, false} | Acc]);
  to_tokens([{Tag0, [B | R1]} | Rest], Acc) when is_binary(B) ->
      Tag = to_tag(Tag0),
      to_tokens([{Tag, R1} | Rest], [{data, binary_to_list(B), false} | Acc]).
  
  test_tokens() ->
      [{start_tag, "foo", [{"bar", "baz"},
  