anchor.diff:    case ff(text,Str) of
       {{tag,""},EStr,{text,Txt}} -> 
         try [Token,{text,Txt}]++tokenize({{tag,""},EStr})
  -      catch _:_ -> tokenize({text,Txt++"&lt;"++EStr,Token})
  +      catch _:_ -> tokenize({text,<<Txt/binary,"&lt;",EStr/binary>>,Token})
         end;
       {{text,Str},"",eof} -> [Token,{eof,{text,Str}}]
     end;
   tokenize({TZ,Str,Token}) ->
     [{Token,{TZ,Str}}].
   
  -tz(nil,"<"++Str)                        -> {{tag,""},ws(Str)};
  -tz(nil,[_|Str])                         -> {nil,Str};
  -
  -tz({tag,""},"!--"++Str)                 -> {{comm,""},Str};
  -tz({tag,""},"!"++Str)                   -> {{excl,""},ws(Str)};
  -tz({tag,""},"?"++Str)                   -> {{que,""},ws(Str)};
  -tz({tag,""},"/"++Str)                   -> {{end_tag,""},ws(Str)};
  -tz({tag,Tag},Str) when ?endv(Str)       -> {{attr,"",{Tag,[]}},ws(Str)};
  -tz({tag,Tag},[X|Str])when ?ok(X)        -> {{tag,Tag++[X]},Str};
  -
  -tz({excl,DT},">"++Str)                  -> {text,Str,{exclamation,dc(DT)}};
  -tz({excl,DT},[X|Str])                   -> {{excl,DT++[X]},Str};
  -
  -tz({que,DT},"?>"++Str)                  -> {text,Str,{question,dc(DT)}};
  -tz({que,DT},[X|Str])                    -> {{que,DT++[X]},Str};
  -
  -tz({comm,Comm},"-->"++Str)              -> {text,Str,{comment,Comm}};
  -tz({comm,Comm},[X|Str])                 -> {{comm,Comm++[X]},Str};
  -
  -tz({etag,Tag,Attrs},"/>"++Str)          -> {text,Str,{sc,Tag,Attrs}};
  -tz({etag,"script",Attrs},">"++Str)      -> {script,Str,{open,"script",Attrs}};
  -tz({etag,"style",Attrs},">"++Str)       -> {style,Str,{open,"style",Attrs}};
  -tz({etag,Tag,Attrs},">"++Str)           -> {text,Str,{open,Tag,Attrs}};
  -
  -tz({end_tag,Tag},Str) when ?endv(Str)   -> {{end_tag,Tag,'>'},ws(Str)};
  -tz({end_tag,Tag,'>'},">"++Str)          -> {text,Str,{close,dc(Tag)}};
  -tz({end_tag,Tag},[X|Str])               -> {{end_tag,Tag++[X]},Str};
  -
  -tz({attr,"",{Tag,As}},S)when ?endv(S)   -> {{etag,dc(Tag),As},S};
  -tz({attr,A,{T,As}},S)when ?endv(S)      -> {{eatt,{dc(A),T,As}},ws(S)};
  -tz({attr,A,TAs},[X|Str])when ?ok(X)     -> {{attr,A++[X],TAs},Str};
  -
  -tz({eatt,ATAs},"="++Str)                -> {{val,ATAs},ws(Str)};
  -tz({eatt,{A,T,As}},S)                   -> {{attr,"",{T,As++[{A,""}]}},ws(S)};
  -
  -tz({val,ATAs},[X|Str])when ?sq(X)       -> {{sqval,"",ATAs},Str};%singlequoted
  -tz({val,ATAs},[X|Str])when ?dq(X)       -> {{dqval,"",ATAs},Str};%doublequoted
  -tz({val,ATAs},Str)                      -> {{uqval,"",ATAs},Str};%unquoted
  -
  -tz({sqval,V,{A,T,As}},[X|S])when ?sq(X) -> {{attr,"",{T,As++[{A,V}]}},ws(S)};
  -tz({sqval,V,ATAs},[X|Str])              -> {{sqval,V++[X],ATAs},Str};
  -
  -tz({dqval,V,{A,T,As}},[X|S])when ?dq(X) -> {{attr,"",{T,As++[{A,V}]}},ws(S)};
  -tz({dqval,V,ATAs},[X|Str])              -> {{dqval,V++[X],ATAs},Str};
  -
  -tz({uqval,V,{A,T,As}},S)when ?endv(S)   -> {{attr,"",{T,As++[{A,V}]}},ws(S)};
  -tz({uqval,V,ATAs},[X|Str])              -> {{uqval,V++[X],ATAs},Str};
  -
  -tz(script,Str)                          -> ff(script,Str);
  -tz(style,Str)                           -> ff(style,Str);
  -tz(text,Str)                            -> ff(text,Str);
  -
  -tz(X,"")                                -> {X,"",eof}.
  +tz(nil,?m("<",Str))                   -> {{tag,""},ws(Str)};
  +tz(nil,?d(_,Str))                     -> {nil,Str};
  +
  +tz({tag,""},?m("!--",Str))            -> {{comm,""},Str};
  +tz({tag,""},?m("!",Str))              -> {{'!',""},ws(Str)};
  +tz({tag,""},?m("?",Str))              -> {{que,""},ws(Str)};
  +tz({tag,""},?m("/",Str))              -> {{end_tag,""},ws(Str)};
  +tz({tag,Tag},?D1(X,S))when ?ev(X)-> {{attr,"",{Tag,[]}},ws(S)};
  +tz({tag,Tag},?D2(X,S))when ?ev(X)-> {{attr,"",{Tag,[]}},ws(S)};
  +tz({tag,Tag},?d(X,Str))when ?ok(X)    -> {{tag,Tag++[X]},Str};
  +
  +tz({'!',DT},?m(">",Str))              -> {text,Str,{'!',dc(DT)}};
  +tz({'!',DT},?d(X,Str))                -> {{'!',DT++[X]},Str};
  +
  +tz({que,DT},?m("?>",Str))             -> {text,Str,{'?',dc(DT)}};
  +tz({que,DT},?d(X,Str))                -> {{que,DT++[X]},Str};
  +
  +tz({comm,Comm},?m("-->",Str))         -> {text,Str,{comment,Comm}};
  +tz({comm,Comm},?d(X,Str))             -> {{comm,Comm++[X]},Str};
  +
  +tz({etag,Tag,Attrs},?m("/>",Str))     -> {text,Str,{sc,Tag,Attrs}};
  +tz({etag,"script",Attrs},?m(">",Str)) -> {script,Str,{open,"script",Attrs}};
  +tz({etag,"style",Attrs},?m(">",Str))  -> {style,Str,{open,"style",Attrs}};
  +tz({etag,Tag,Attrs},?m(">",Str))      -> {text,Str,{open,Tag,Attrs}};
  +
  +tz({end_tag,Tag},?D1(X,S))when ?ev(X) -> {{end_tag,Tag,'>'},ws(S)};
  +tz({end_tag,Tag},?D2(X,S))when ?ev(X) -> {{end_tag,Tag,'>'},ws(S)};
  +tz({end_tag,Tag,'>'},?m(">",Str))     -> {text,Str,{close,dc(Tag)}};
  +tz({end_tag,Tag},?d(X,Str))           -> {{end_tag,Tag++[X]},Str};
  +
  +tz({attr,"",{Tag,As}},?D1(X,S))when ?ev(X) -> {{etag,dc(Tag),As},S};
  +tz({attr,"",{Tag,As}},?D2(X,S))when ?ev(X) -> {{etag,dc(Tag),As},S};
  +tz({attr,A,{T,As}},?D1(X,S))when ?ev(X)    -> {{eatt,{dc(A),T,As}},ws(S)};
  +tz({attr,A,{T,As}},?D2(X,S))when ?ev(X)    -> {{eatt,{dc(A),T,As}},ws(S)};
  +tz({attr,A,TAs},?d(X,Str))when ?ok(X) -> {{attr,A++[X],TAs},Str};
  +
  +tz({eatt,ATAs},?m("=",Str))           -> {{val,ATAs},ws(Str)};
  +tz({eatt,{A,T,As}},S)                 -> {{attr,"",{T,As++[{A,""}]}},ws(S)};
  +
  +tz({val,ATAs},?m("'",Str))            -> {{sqval,"",ATAs},Str};%singlequoted
  +tz({val,ATAs},?m("\"",Str))           -> {{dqval,"",ATAs},Str};%doublequoted
  +tz({val,ATAs},Str)                    -> {{uqval,"",ATAs},Str};%unquoted
  +
  +tz({sqval,V,{A,T,As}},?m("'",S))      -> {{attr,"",{T,As++[{A,V}]}},ws(S)};
  +tz({sqval,V,ATAs},?d(X,Str))          -> {{sqval,V++[X],ATAs},Str};
  +
  +tz({dqval,V,{A,T,As}},?m("\"",S))     -> {{attr,"",{T,As++[{A,V}]}},ws(S)};
  +tz({dqval,V,ATAs},?d(X,Str))          -> {{dqval,V++[X],ATAs},Str};
  +
  +tz({uqval,V,{A,T,As}},?D1(X,S))when ?ev(X) -> {{attr,"",{T,As++[{A,V}]}},ws(S)};
  +tz({uqval,V,{A,T,As}},?D2(X,S))when ?ev(X) -> {{attr,"",{T,As++[{A,V}]}},ws(S)};
  +tz({uqval,V,ATAs},?d(X,Str))          -> {{uqval,V++[X],ATAs},Str};
  +
  +tz(script,Str)                        -> ff(script,Str);
  +tz(style,Str)                         -> ff(style,Str);
  +tz(text,Str)                          -> ff(text,Str);
  +
  +tz(X,"")                              -> {X,"",eof}.
   
   ff(What,Str) ->
     case ff(Str,ff(What),[1,2]) of
  
positive.code:      {end_tag,"tag"}]},
     {"<a href=/a/bc/d.e>x</a>",
      [{tag,"a",[{"href","/a/bc/d.e"}]},
       {text,"x"},
       {end_tag,"a"}]},
     {"<a>...<...</a>",
      [{tag,"a",[]},
       {text,"...&lt;..."},
       {end_tag,"a"}]},
     {"<P a=b c=d>hej<!-- tobbe --><b>svejsan</b>foo</p>grump<x x=y />",
      [{tag,"p",[{"a","b"},{"c","d"}]},
       {text,"hej"},
       {comment," tobbe "},
       {tag,"b",[]},
       {text,"svejsan"},
       {end_tag,"b"},
       {text,"foo"},
       {end_tag,"p"},
       {text,"grump"},
       {tag,"x",[{"x","y"}]},
       {end_tag,"x"}]}
    ].
  
negative.code: 
  tests() ->
    [{"<!DOCTYPE bla><P a=b c=d>",
      [{'!',"doctype bla"},
       {tag,"p",[{"a","b"},{"c","d"}]},
       {end_tag,"p"}]},
     {"<head><B>< p><p ></z></ b></x>",
  