HTMLDiff problem

I'd a problem with Instiki's usage of HTMLDiff. Assume you've these two strings

  X <b>Y</b> Z
  X <i>Y</i> Z

Applying HTMLDiff.diff on those strings results in

  X
  <del class="diffmod"><b></del>
  <ins class="diffmod"><i></ins>
  Y
  <del class="diffmod"></b></del>
  <ins class="diffmod"></i></ins>
  Z

And I'm pretty sure this isn't valid HTML. At least Mozilla 1.7RC3 can't render a larger Instiki page with lot's of similar code correctly.

Is there anything I can do about?

I found a workaround by adding these lines to Builder#op_helper:

  def op_helper(tagname, tagclass, to_add)
   if to_add.size == 1 and to_add.first =~
         /^<\/?(b|i|tt|em|strong|code)>$/
     @content << to_add.first if tagname == "ins"
     to_add = []
   end
   ...

In case that the diff is just an opening or closing tag, drop the old tag and insert the new tag outside the diff. Some other method will take care of empty diff tags so they're no problem.

bye

···

--
Stefan Matthias Aust // "Zweifel sind der Ansporn des Denkens..." -U

In case anybody cares, I think I fixed the problem by filtering the contents of "to_add" through this method. My first attempt was to naive... Now Instiki generates nice diffs again :slight_smile:

   def self.balance_inline_tags(tags)
     result = []
     stack = []
     tags.each do |t|
       if t =~ /^<(\/)?(b|i|tt|em|strong|code|span)/
         if $1 # endtag
           if stack.last == $2
             stack.pop
           else
             # unbalanced end tag, generate start tag
             result.unshift "<#$2>"
           end
         else
           stack.push $2
         end
       end
       result << t
     end
     # unbalanced start tags, generate end tags
     stack.reverse_each {|t| result << "</#{t}>"}
     result
   end

bye

···

--
Stefan Matthias Aust // "Zweifel sind der Ansporn des Denkens..." -U