anchor.diff:  %% Var = atom()
   ehtml_expander_compress([Tag|T], Acc) when tuple(Tag) ->
       [list_to_binary(reverse(Acc)), Tag | ehtml_expander_compress(T, [])];
  -ehtml_expander_compress([], Acc) ->
  -    [list_to_binary(reverse(Acc))];
  +ehtml_expander_compress([], Acc) -> [list_to_binary(reverse(Acc))];
   ehtml_expander_compress([H|T], Acc) when integer(H) ->
       ehtml_expander_compress(T, [H|Acc]).
   
   %% Apply an expander with the variable bindings in Env.  Env is a list of
   %% {VarName, Value} tuples, where VarName is an atom and Value is an ehtml
   %% term.
  -ehtml_apply(Expander, Env) ->
  -    [ehtml_eval(X, Env) || X <- Expander].
  -
  -ehtml_eval(Bin, Env) when binary(Bin) ->
  -    Bin;
  +ehtml_apply(Expander, Env) -> [ehtml_eval(X, Env) || X <- Expander].
  +
  +ehtml_eval(Bin, Env) when binary(Bin) -> Bin;
   ehtml_eval({Type, Var}, Env) ->
       case lists:keysearch(Var, 1, Env) of
  -	false ->
  -	    exit({ehtml_unbound, Var});
  +	false -> exit({ehtml_unbound, Var});
   	{value, {Var, Val}} ->
   	    case Type of
  -		ehtml ->
  -		    ehtml_expand(Val);
  -		preformatted ->
  -		    Val;
  -		ehtml_attrs ->
  -		    ehtml_attrs(Val)
  +		ehtml -> ehtml_expand(Val);
  +		preformatted -> Val;
  +		ehtml_attrs -> ehtml_attrs(Val)
   	    end
       end.
   
  
positive.code: %% Key 	 = atom()
  %% Value = string()
  %% Body  = EHTML
  ehtml_expand(Ch) when Ch >= 0, Ch =< 255 ->
      yaws_api:htmlize_char(Ch);
  ehtml_expand(Bin) when binary(Bin) ->
      yaws_api:htmlize(Bin);
  ehtml_expand({Tag}) ->
      ehtml_expand({Tag,[]});
  ehtml_expand({pre_html, X}) ->
      X;
  ehtml_expand({pre, Attrs}) ->
      ["<pre", ehtml_attrs(Attrs), ">"];
  ehtml_expand({Tag, Attrs}) ->
      ["<", atom_to_list(Tag), ehtml_attrs(Attrs), ">"];
  ehtml_expand({Tag, Attrs, Body}) when atom(Tag) ->
      Ts = atom_to_list(Tag),
      ["<",Ts, ehtml_attrs(Attrs),">",
       ehtml_expand(Body),
       "</", Ts, ">"];
  ehtml_expand([H|T]) ->
      [ehtml_expand(H) | ehtml_expand(T)];
  ehtml_expand([]) ->
      [].
  
  
  ehtml_attrs([]) ->
      [];
  ehtml_attrs([Attribute|Tail]) when atom(Attribute) ->
      [[$ |atom_to_list(Attribute)]|ehtml_attrs(Tail)];
  ehtml_attrs([{Name, Value} | Tail]) ->
      ValueString = if atom(Value) -> [$",atom_to_list(Value),$"];
  		     list(Value) -> [$",Value,$"]
  		  end,
      [[$ |atom_to_list(Name)], [$=|ValueString]| ehtml_attrs(Tail)].
  
  
  %% ------------------------------------------------------------
  %% ehtml_expander/1: an EHTML optimizer
  
negative.code: %% e.g. ehtml_var_name('$foo') -> foo.
  ehtml_var_name(A) when atom(A) ->
      case ehtml_var_p(A) of
  	true -> list_to_atom(tl(atom_to_list(A)));
  	false -> exit({bad_ehtml_var_name, A})
      end.
  
  %% Is X a variable reference? Variable references are atoms starting with $.
  ehtml_var_p(X) when atom(X) -> hd(atom_to_list(X)) == $$;
  ehtml_var_p(_) -> false.
  
  ehtml_expander_test() ->
      %% Expr is a template containing variables.
  