render(); */ require_once 'Text/Diff.php'; class CharDiff extends Text_MappedDiff { function CharDiff ($text_src, $text_tgt) { $chars_src = str_split($text_src, 1); $chars_tgt = str_split($text_tgt, 1); $chars_src_mapped = $chars_src; $chars_tgt_mapped = $chars_tgt; parent::Text_MappedDiff($chars_src, $chars_tgt, $chars_src_mapped, $chars_tgt_mapped); } function getStat() { $stat = array(); $stat['copy'] = 0; $stat['add'] = 0; $stat['del'] = 0; $stat['change'] = 0; $stat['change-del'] = 0; $stat['change-add'] = 0; foreach($this->getDiff() as $op) { if (is_a($op, 'Text_Diff_Op_copy')) $stat['copy'] += $op->norig(); if (is_a($op, 'Text_Diff_Op_delete')) $stat['del'] += $op->norig(); if (is_a($op, 'Text_Diff_Op_add')) $stat['add'] += $op->nfinal(); if (is_a($op, 'Text_Diff_Op_change')) { $stat['change-del'] += $op->norig(); $stat['change-add'] += $op->nfinal(); } } return $stat; } function render($color_delete = 'red', $color_add = 'green') { foreach ($this->getDiff() as $op) { if (is_a(&$op,'Text_Diff_Op_copy')) { echo $this->_implode($op->final); } elseif (is_a(&$op,'Text_Diff_Op_delete')) { echo '', $this->_implode($op->orig), ''; } elseif (is_a(&$op,'Text_Diff_Op_add')) { echo '', $this->_implode($op->final), ''; } elseif (is_a(&$op,'Text_Diff_Op_change')) { echo '', $this->_implode($op->orig), ''; echo '', $this->_implode($op->final), ''; } } return $return; } function _implode($chars) { return nl2br( implode('', array_map( array($this, '_htmlFilter'), $chars) ) ); } // used with array_map function _htmlFilter($text) { return $text = str_replace( array('&', '<', '>'), array('&', '<', '>'), $text); } }