anchor.diff:  	true  -> {preformatted, ehtml_var_name(A)};
   	false -> atom_to_list(A)
       end;
  -ehtml_attr_part_expander(I) when integer(I) ->
  -    integer_to_list(I);
  -ehtml_attr_part_expander(S) when list(S) ->
  -    S.
  -
  -ehtml_expander_done(X, Before, After) ->
  -    [reverse([X|Before]), After].
  +ehtml_attr_part_expander(I) when integer(I) -> integer_to_list(I);
  +ehtml_attr_part_expander(S) when list(S) -> S.
  +
  +ehtml_expander_done(X, Before, After) -> [reverse([X|Before]), After].
   
   %% Compress an EHTML expander, converting all adjacent bits of text into
   %% binaries.
  
positive.code: 			 ehtml_attrs_expander(Attrs),">"],
  			Before,
  			After);
  ehtml_expander({Tag, Attrs}, Before, After) ->
      ehtml_expander_done(["<",atom_to_list(Tag),
  			 ehtml_attrs_expander(Attrs),">"],
  			Before,
  			After);
  ehtml_expander({Tag, Attrs, Body}, Before, After) ->
      ehtml_expander(Body,
  		   [["<",atom_to_list(Tag), ehtml_attrs_expander(Attrs), ">"] |
  		    Before],
  		   ["</",atom_to_list(Tag),">" | After]);
  %% Variable references
  ehtml_expander(Var, Before, After) when atom(Var) ->
      [reverse(Before), {ehtml, ehtml_var_name(Var)}, After];
  %% Lists
  ehtml_expander([H|T], Before, After) ->
      ehtml_expander(T, [ehtml_expander(H, [], []) | Before], After);
  ehtml_expander([], Before, After) ->
      ehtml_expander_done("", Before, After).
  
  
  %% Expander for attributes. The attribute name and value can each be a
  %% variable reference.
  ehtml_attrs_expander([]) ->
      "";
  ehtml_attrs_expander([{Var,Val}|T]) ->
      [[" ",
        ehtml_attr_part_expander(Var),
        "=",
        "\"", ehtml_attr_part_expander(Val), "\""]
       | ehtml_attrs_expander(T)];
  ehtml_attrs_expander(Var) when atom(Var) ->
      %% Var in the cdr of an attribute list
      [{ehtml_attrs, ehtml_var_name(Var)}].
  
negative.code: %% 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([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_eval({Type, Var}, Env) ->
      case lists:keysearch(Var, 1, Env) of
  	false -> exit({ehtml_unbound, Var});
  	{value, {Var, Val}} ->
  	    case Type of
  		ehtml -> ehtml_expand(Val);
  		preformatted -> Val;
  		ehtml_attrs -> ehtml_attrs(Val)
  	    end
      end.
  
  