anchor.diff:  %% @author Marc Worrell <marc@worrell.nl>
  -%% @copyright 2009 Marc Worrell
  +%% @copyright 2009-2012 Marc Worrell
   %% Date: 2009-04-17
   %%
   %% @doc Utility functions for html processing.  Also used for property filtering (by m_rsc_update).
   
  -%% Copyright 2009 Marc Worrell
  +%% Copyright 2009-2012 Marc Worrell
   %%
   %% Licensed under the Apache License, Version 2.0 (the "License");
   %% you may not use this file except in compliance with the License.
  
positive.code: sanitize({trans, Tr}, OptContext) ->
      {trans, [{Lang, sanitize(V, OptContext)} || {Lang,V} <- Tr]};
  sanitize(Html, OptContext) when is_binary(Html) ->
      sanitize1(<<"<sanitize>",Html/binary,"</sanitize>">>, OptContext);
  sanitize(Html, OptContext) when is_list(Html) ->
      sanitize1(iolist_to_binary(["<sanitize>", Html, "</sanitize>"]), OptContext).
  
  sanitize1(Html, OptContext) ->
      Parsed = mochiweb_html:parse(ensure_escaped_amp(Html)),
      Sanitized = sanitize(Parsed, [], OptContext),
      flatten(Sanitized).
  
      sanitize(B, _Stack, _OptContext) when is_binary(B) ->
          escape(B);
      sanitize({comment, Text}, _Stack, _OptContext) ->
          {comment, Text};
      sanitize({pi, _Raw}, _Stack, _OptContext) ->
          <<>>;
      sanitize({pi, _Tag, _Attrs}, _Stack, _OptContext) ->
          <<>>;
      sanitize({Elt,Attrs,Enclosed}, Stack, OptContext) ->
          Lower = list_to_binary(z_string:to_lower(Elt)),
          case allow_elt(Lower) orelse (not lists:member(Lower, Stack) andalso allow_once(Lower)) of
              true ->
                  Attrs1 = lists:filter(fun({A,_}) -> allow_attr(A) end, Attrs),
                  Attrs2 = [ {list_to_binary(z_string:to_lower(A)), V} || {A,V} <- Attrs1 ],
                  Stack1 = [Lower|Stack],
                  Tag = { Lower, 
                          Attrs2,
                          [ sanitize(Encl, Stack1, OptContext) || Encl <- Enclosed ]},
                  case OptContext of
                      #context{} -> z_notifier:foldl(sanitize_element, Tag, OptContext);
                      undefined -> Tag
  
negative.code:             false ->
                  case skip_contents(Lower) of
                      false ->
                          {nop, [ sanitize(Encl, Stack, ExtraElts, ExtraAttrs, OptContext) || Encl <- Enclosed ]};
                      true ->
                          {nop, []}
                  end
  