The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
package MojoMojo::WordDiff;

# based on Text::WordDiff, but with many differences.

use strict;
use HTML::Entities;
use base qw(Exporter);
use Algorithm::Diff;

our @EXPORT = qw(word_diff);

sub _split_html_str {
  my $str = shift;
  my @array;
  my @tags = split qr/(?:(?<=>)|(?=<))/msx, $str;
  foreach(@tags) {
    if(length($_) == 0) {
      next;
    }
    if($_ =~ /^</) {
      push @array, $_;
    } else {
      my $tmp_str = decode_entities($_);
      my @tmp_arr = split qr/(?:(?<!\p{IsWord})(?=\p{IsWord})|(?<!\p{IsSpace})(?=\p{IsSpace})|(?<!\p{IsPunct})(?=\p{IsPunct}))/msx, $tmp_str;
      @tmp_arr = map {$_ = encode_entities($_)} @tmp_arr;
      push @array, @tmp_arr;
    }
  }
  return @array;
}

sub word_diff {
  my @args = map {my @a = _split_html_str($_); \@a;} @_;
  my $diff = Algorithm::Diff->new(@args);
  my $out = "";
  while ($diff->Next) {
    if (my @same = $diff->Same) {
      $out .= (join '', @same);
    }
    else {
      if (my @del = $diff->Items(1)) {
        $out .= '<del>' . (join '', @del) . '</del>';
      }
      if (my @ins = $diff->Items(2)) {
        $out .= '<ins>' . (join '', @ins) . '</ins>';
      }
    }
  }
  return $out;
}

=head1 NAME

MojoMojo::WordDiff - generate inline word-based HTML diffs

=head1 DESCRIPTION

Creates a word by word line diff for lines that are changed.

=head1 METHODS

=head2 word_diff

Takes two conflicting lines, and returns a line with the diff in HTML.

=head2 

=cut

1;