anchor.diff:  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   
   parse({UrlRefs, ImgRefs, TypedLines}) ->
  -    % io:format("in parse UrlRefs are ~p~n" ++
  -    %          "ImgRefs are ~p~n" ++
  -    %          "TypedLines are ~p~n",
  -    %          [UrlRefs, ImgRefs, TypedLines]),
       p1(TypedLines, UrlRefs, ImgRefs, [], []).
   
   %% goes through the lines
   %% If it hits a 'start' like 'blockquote' it throws a HTML fragment into the mix
   %% (eg <blockquote>) and then the matching closing one onto the stack (eg </blockquote>)
  +
   %% when it hits a hard return it then throws the matching closing one back in...
  -p1([], _Urls, _Imgs, [], Acc) ->
  -    flatten(reverse(Acc)); 
  -p1([], _Urls, _Imgs, Stack, Acc) ->
  -    flatten(reverse([reverse(Stack) | Acc]));
  +p1([], _U, _I, [], Acc)    -> flatten(reverse(Acc)); 
  +p1([], _U, _I, Stack, Acc) -> flatten(reverse([reverse(Stack) | Acc]));
   
   %% Tags have the highest precedence...
  -p1([{tag, Tag} | T], Urls, Imgs, Stack, Acc) ->
  +p1([{tag, Tag} | T], U, I, Stack, Acc) ->
       case T of
  -        [{blank, _} | T2] -> p1(T2, Urls, Imgs, Stack,
  +        [{blank, _} | T2] -> p1(T2, U, I, Stack,
                                   [make_tag_str(Tag) | Acc]);
  -        _Other            -> p1(T, Urls, Imgs, Stack,
  -                                ["<p>" ++ make_str(Tag) ++ "</p>" | Acc])
  +        _Other            -> p1(T, U, I, Stack,
  +                                ["<p>" ++ make_str(Tag, U, I) ++ "</p>" | Acc])
       end;
   %% These clauses handle state issues
   %% hit a blank line - you close the last open state (if it exists) and
   %% throw a <br />
  -p1([{blank, _} | T], Urls, Imgs, [], Acc) ->
  -    p1(T, Urls, Imgs, [], ["<br />" | Acc]); 
  -p1([{blank, _} | T], Urls, Imgs, [Close | Open], Acc) ->
  -    p1(T, Urls, Imgs, Open, flatten(["<br />", Close | Acc]));
  +p1([{blank, _} | T], U, I, [], Acc) ->
  +    p1(T, U, I, [], ["<br />" | Acc]); 
  +p1([{blank, _} | T], U, I, [Close | Open], Acc) ->
  +    p1(T, U, I, Open, flatten(["<br />", Close | Acc]));
  +
   %% two consecutive normal lines should be concatenated..
  -p1([{normal, P1}, {normal, P2} | T], Urls, Imgs, Stack, Acc) ->
  -    p1([{normal, flatten([P1 | P2])} | T], Urls, Imgs, Stack, Acc);
  +p1([{normal, P1}, {normal, P2} | T], U, I, Stack, Acc) ->
  +    p1([{normal, flatten([P1 | P2])} | T], U, I, Stack, Acc);
  +
   %% setext h1 is a look behind
  -p1([{normal, P}, {setext_h1, _} | T], Urls, Imgs, Stack, Acc) ->
  -    p1(T, Urls, Imgs, Stack, ["<h1>" ++ make_str(snip(P)) ++ "</h1>" | Acc]); 
  +p1([{normal, P}, {setext_h1, _} | T], U, I, Stack, Acc) ->
  +    p1(T, U, I, Stack, ["<h1>" ++ make_str(snip(P), U, I) ++ "</h1>" | Acc]); 
  +
   %% setext h2 might be a look behind
  -p1([{normal, P}, {h2_or_hr, _} | T], Urls, Imgs, Stack, Acc) ->
  -    p1(T, Urls, Imgs, Stack, ["<h2>" ++ make_str(snip(P)) ++ "</h2>" | Acc]); 
  +p1([{normal, P}, {h2_or_hr, _} | T], U, I, Stack, Acc) ->
  +    p1(T, U, I, Stack, ["<h2>" ++ make_str(snip(P), U, I) ++ "</h2>" | Acc]); 
  +
   %% blockquote is look ahead push blockquote onto the state
  -p1([{blockquote, _P} | T], Urls, Imgs, Stack, Acc) ->
  -    p1(T, Urls, Imgs, ["</blockquote>" | Stack], ["<blockquote>" | Acc]);
  +p1([{blockquote, _P} | T], U, I, Stack, Acc) ->
  +    p1(T, U, I, ["</blockquote>" | Stack], ["<blockquote>" | Acc]);
  +
   %% but one is just normal...
  -p1([{normal, P} | T], Urls, Imgs, Stack, Acc) ->
  -    p1(T, Urls, Imgs, Stack, ["<p>" ++ make_str(snip(P)) ++ "</p>" | Acc]);
  +p1([{normal, P} | T], U, I, Stack, Acc) ->
  +    p1(T, U, I, Stack, ["<p>" ++ make_str(snip(P), U, I) ++ "</p>" | Acc]);
  +
   %% atx headings
  -p1([{{h1, P}, _} | T], Urls, Imgs, Stack, Acc) ->
  -    p1(T, Urls, Imgs, Stack, ["<h1>" ++ string:strip(P, right) ++ "</h1>" | Acc]); 
  -p1([{{h2, P}, _} | T], Urls, Imgs, Stack, Acc) ->
  -    p1(T, Urls, Imgs, Stack, ["<h2>" ++ string:strip(P) ++ "</h2>" | Acc]); 
  -p1([{{h3, P}, _} | T], Urls, Imgs, Stack, Acc) ->
  -    p1(T, Urls, Imgs, Stack, ["<h3>" ++ string:strip(P) ++ "</h3>" | Acc]); 
  -p1([{{h4, P}, _} | T], Urls, Imgs, Stack, Acc) ->
  -    p1(T, Urls, Imgs, Stack, ["<h4>" ++ string:strip(P) ++ "</h4>" | Acc]); 
  -p1([{{h5, P}, _} | T], Urls, Imgs, Stack, Acc) ->
  -    p1(T, Urls, Imgs, Stack, ["<h5>" ++ string:strip(P) ++ "</h5>" | Acc]); 
  -p1([{{h6, P}, _} | T], Urls, Imgs, Stack, Acc) ->
  -    p1(T, Urls, Imgs, Stack, ["<h6>" ++ string:strip(P) ++ "</h6>" | Acc]);
  +p1([{{h1, P}, _} | T], U, I, Stack, Acc) ->
  +    NewP = string:strip(make_str(P, U, I), right),
  +    p1(T, U, I, Stack, ["<h1>" ++ NewP ++ "</h1>" | Acc]); 
  +p1([{{h2, P}, _} | T], U, I, Stack, Acc) ->
  +    NewP = string:strip(make_str(P, U, I), right),
  +    p1(T, U, I, Stack, ["<h2>" ++ NewP ++ "</h2>" | Acc]); 
  +p1([{{h3, P}, _} | T], U, I, Stack, Acc) ->
  +    NewP = string:strip(make_str(P, U, I), right),
  +    p1(T, U, I, Stack, ["<h3>" ++ NewP ++ "</h3>" | Acc]); 
  +p1([{{h4, P}, _} | T], U, I, Stack, Acc) ->
  +    NewP = string:strip(make_str(P, U, I), right),
  +    p1(T, U, I, Stack, ["<h4>" ++ NewP ++ "</h4>" | Acc]); 
  +p1([{{h5, P}, _} | T], U, I, Stack, Acc) ->
  +    NewP = string:strip(make_str(P, U, I), right),
  +    p1(T, U, I, Stack, ["<h5>" ++ NewP ++ "</h5>" | Acc]); 
  +p1([{{h6, P}, _} | T], U, I, Stack, Acc) ->
  +    NewP = string:strip(make_str(P, U, I), right),
  +    p1(T, U, I, Stack, ["<h6>" ++ NewP ++ "</h6>" | Acc]); 
  +
   %% unordered lists
  -p1([{{ul, _P}, _} | _T] = List, Urls, Imgs, Stack, Acc) ->
  -    {Rest, NewAcc} = parse_list(ul, List, Urls, Imgs, []),
  -    p1(Rest, Urls, Imgs, Stack, ["<ul>" ++ NewAcc ++ "</ul>" | Acc]);
  +p1([{{ul, _P}, _} | _T] = List, U, I, Stack, Acc) ->
  +    {Rest, NewAcc} = parse_list(ul, List, U, I, []),
  +    p1(Rest, U, I, Stack, ["<ul>" ++ NewAcc ++ "</ul>" | Acc]);
  +
   %% unordered lists
  -p1([{{ol, _P}, _} | _T] = List, Urls, Imgs, Stack, Acc) ->
  -    {Rest, NewAcc} = parse_list(ol, List, Urls, Imgs, []),
  -    p1(Rest, Urls, Imgs, Stack, ["<ol>" ++ NewAcc ++ "</ol>" | Acc]);
  +p1([{{ol, _P}, _} | _T] = List, U, I, Stack, Acc) ->
  +    {Rest, NewAcc} = parse_list(ol, List, U, I, []),
  +    p1(Rest, U, I, Stack, ["<ol>" ++ NewAcc ++ "</ol>" | Acc]);
  +
   %% codeblock
  -p1([{{codeblock, P}, _} | T], Urls, Imgs, Stack, Acc) ->
  -    p1(T, Urls, Imgs, Stack, ["<pre><code>" ++ make_str(P) ++ "</code></pre>" | Acc]);
  -
  -p1([{br, P} | T], Urls, Imgs, Stack, Acc) ->
  -    p1(T, Urls, Imgs, Stack, [P | Acc]).
  +p1([{{codeblock, P}, _} | T], U, I, Stack, Acc) ->
  +    p1(T, U, I, Stack, ["<pre><code>" ++ make_str(P, U, I)
  +                        ++ "</code></pre>" | Acc]);
  +
  +%% horizontal rules
  +p1([{hr, _} | T], U, I, Stack, Acc) ->
  +    p1(T, U, I, Stack, ["<hr />" | Acc]);
  +%% the clause with a normal before an 'h2_or_hr' has already been
  +%% handled further up the tree, so this is a bona fide 'hr'...
  +p1([{h2_or_hr, _} | T], U, I, Stack, Acc) ->
  +    p1(T, U, I, Stack, ["<hr />" | Acc]); 
  +
  +%% line breaks - and that's us
  +p1([{br, P} | T], U, I, Stack, Acc) ->
  +    p1(T, U, I, Stack, [P | Acc]).
   
   %% this is a bit messy because of the way that hard lines are treated...
   %% If your li's have a blank line between them the item gets wrapped in a para,
   %% if not, they don't
  -parse_list(_Type, [], _Urls, _Imgs, A) ->
  +parse_list(_Type, [], _U, _I, A) ->
       {[], reverse(A)};
   %% if the '<li>' is followed by a blank then wrap it, throw the blank
   %% back onto the tail
  -parse_list(Type, [{{Type, P}, _}, {blank, _} = B | T], _Urls, _Imgs, A) ->
  -     parse_list(Type, [B | T], _Urls, _Imgs, ["<li><p>" ++ P ++ "</p></li>" | A]);
  +parse_list(Type, [{{Type, P}, _}, {blank, _} = B | T], U, I, A) ->
  +     parse_list(Type, [B | T], U, I, ["<li><p>" ++ make_esc_str(P, U, I)
  +                                      ++ "</p></li>" | A]);
   %% this is the partner of the previous line...
  -parse_list(Type, [{blank, _}, {{Type, P}, _} | T], _Urls, _Imgs, A) ->
  -    {Rest, NewP} = grab(T, []),
  -    parse_list(Type, Rest, _Urls, _Imgs, ["<li><p>" ++ P ++ NewP ++"</p></li>" | A]);
  -
  +parse_list(Type, [{blank, _}, {{Type, P}, _} | T], U, I, A) ->
  +    {Rest, NewP} = grab(T, U, I, []),
  +    parse_list(Type, Rest, U, I, ["<li><p>" ++ make_esc_str(P, U, I)
  +                                  ++ NewP ++"</p></li>" | A]);
   %% this is a plain old '<li>'
  -parse_list(Type, [{{Type, P}, _} | T], _Urls, _Imgs, A) ->
  -    {Rest, NewP} = grab(T, []),
  -    parse_list(Type, Rest, _Urls, _Imgs, ["<li>" ++ P ++ NewP ++ "</li>" | A]);
  -parse_list(_Type, List, _Urls, _Imgs, A) ->
  +parse_list(Type, [{{Type, P}, _} | T], U, I, A) ->
  +    {Rest, NewP} = grab(T, U, I, []),
  +    parse_list(Type, Rest, U, I, ["<li>" ++ make_esc_str(P, U, I)
  +                                  ++ NewP ++ "</li>" | A]);
  +parse_list(_Type, List, _U, _I, A) ->
       {List, reverse(A)}.
   
   %% grab grabs normals and double codeblocks
  -grab([{{codeblock, _}, S} | T] = List, Acc) ->
  +grab([{{codeblock, _}, S} | T] = List, U, I, Acc) ->
       case is_blockquote(S, T) of
  -        {{true, R1}, T2}       -> grab(T2, ["</blockquote>",% Putting Tags
  -                                            make_str(R1),   % on backwards!
  -                                            "<blockquote>"
  -                                            | Acc]);
  -        {{esc_false, R1}, _T2} -> {R1, reverse(Acc)};       % escaped >
  +        {{true, R1}, T2}       -> grab(T2, U, I,
  +                                       ["</blockquote>",
  +                                        make_esc_str(R1, U, I),
  +                                        "<blockquote>" | Acc]);
  +        {{esc_false, R1}, _T2} -> {R1, reverse(Acc)};
           {false, T2}            -> 
               case is_double_indent(S) of  % try codeblock
                   false      -> {List, reverse(Acc)};
  -                {true, R2} -> grab(T2, [make_str(R2), "<br />" | Acc])
  +                {true, R2} ->
  +                    grab(T2, U, I, [make_esc_str(R2, U, I), "<br />" | Acc])
               end
       end;
  -grab([{normal, P} | T], Acc) -> grab(T, [make_str(P) | Acc]);
  -grab(List, Acc)              -> {List, reverse(Acc)}.
  +grab([{normal, P} | T], U, I, Acc) ->
  +    grab(T, U, I, [make_esc_str(P, U, I) | Acc]);
  +grab(List, _U, _I, Acc) -> {List, reverse(Acc)}.
   
   is_double_indent(List) -> is_double_indent1(List, 0).
   
  
positive.code:     end.
  
  type_ws1([])                        -> blank;
  type_ws1([{{linefeed, _}, _} | []]) -> blank;
  type_ws1([[] | T])                  -> type_ws1(T);
  type_ws1([{{ws, _}, _} | T])        -> type_ws1(T);
  type_ws1(_L)                        -> try_codeblock.
  
negative.code:     t_l1(T, A1, A2, [type_star(H) | A3]);
  
  %% <BR /> typing
  t_l1([[{br, P}] | T], A1, A2, A3) ->
      t_l1(T, A1, A2, [{br, P} | A3]);
  
  %% Block level tags - these are look ahead they must be
  %% on a single line (ie directly followed by a lf and nothing else
  t_l1([[{{{tag, _Type}, Tag}, _} = H | T1] = List | T], A1, A2, A3) ->
      case is_blank(T1) of
          false -> t_l1(T, A1, A2, [{normal , List} | A3]);
  