From 812bb04e971a47bee7e0da80d93831f1660efafb Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sat, 20 Nov 2010 11:53:38 +0100 Subject: Add support for inline diff formatting This patch only adds the capability to the Difference Engine lib, not to the user interface, yet. --- inc/DifferenceEngine.php | 115 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) (limited to 'inc') diff --git a/inc/DifferenceEngine.php b/inc/DifferenceEngine.php index 7eae8bd93..a56fe9f6e 100644 --- a/inc/DifferenceEngine.php +++ b/inc/DifferenceEngine.php @@ -838,6 +838,10 @@ class _HWLDF_WordAccumulator { if ($this->_group !== '') { if ($this->_tag == 'mark') $this->_line .= ''.$this->_group.''; + elseif ($this->_tag == 'add') + $this->_line .= ''.$this->_group.''; + elseif ($this->_tag == 'del') + $this->_line .= ''.$this->_group.''; else $this->_line .= $this->_group; } @@ -918,6 +922,42 @@ class WordLevelDiff extends MappedDiff { } } +class InlineWordLevelDiff extends MappedDiff { + + function InlineWordLevelDiff($orig_lines, $closing_lines) { + list ($orig_words, $orig_stripped) = $this->_split($orig_lines); + list ($closing_words, $closing_stripped) = $this->_split($closing_lines); + + $this->MappedDiff($orig_words, $closing_words, $orig_stripped, $closing_stripped); + } + + function _split($lines) { + if (!preg_match_all('/ ( [^\S\n]+ | [0-9_A-Za-z\x80-\xff]+ | . ) (?: (?!< \n) [^\S\n])? /xs', + implode("\n", $lines), $m)) { + return array(array(''), array('')); + } + return array($m[0], $m[1]); + } + + function inline() { + $orig = new _HWLDF_WordAccumulator; + foreach ($this->edits as $edit) { + if ($edit->type == 'copy') + $orig->addWords($edit->orig); + elseif ($edit->type == 'change'){ + $orig->addWords($edit->orig, 'del'); + $orig->addWords($edit->closing, 'add'); + } elseif ($edit->type == 'delete') + $orig->addWords($edit->orig, 'del'); + elseif ($edit->type == 'add') + $orig->addWords($edit->closing, 'add'); + elseif ($edit->orig) + $orig->addWords($edit->orig, 'del'); + } + return $orig->getLines(); + } +} + /** * "Unified" diff formatter. * @@ -1042,5 +1082,80 @@ class TableDiffFormatter extends DiffFormatter { } } +/** + * Inline style diff formatter. + * + */ +class InlineDiffFormatter extends DiffFormatter { + + function InlineDiffFormatter() { + $this->leading_context_lines = 2; + $this->trailing_context_lines = 2; + } + + function format($diff) { + // Preserve whitespaces by converting some to non-breaking spaces. + // Do not convert all of them to allow word-wrap. + $val = parent::format($diff); + $val = str_replace(' ','  ', $val); + $val = preg_replace('/ (?=<)|(?<=[ >]) /', ' ', $val); + return $val; + } + + function _pre($text){ + $text = htmlspecialchars($text); + return $text; + } + + function _block_header($xbeg, $xlen, $ybeg, $ylen) { + global $lang; + if ($xlen != 1) + $xbeg .= "," . $xlen; + if ($ylen != 1) + $ybeg .= "," . $ylen; + $r = '@@ '.$lang['line']." -$xbeg +$ybeg @@"; + $r .= ' '.$lang['deleted'].''; + $r .= ' '.$lang['created'].''; + $r .= "\n"; + return $r; + } + + function _start_block($header) { + print($header."\n"); + } + + function _end_block() { + } + + function _lines($lines, $prefix=' ', $color="white") { + } + + function _added($lines) { + foreach ($lines as $line) { + print(''. $line . "\n"); + } + } + + function _deleted($lines) { + foreach ($lines as $line) { + print('' . $line . "\n"); + } + } + + function _context($lines) { + foreach ($lines as $line) { + print(''.$line."\n"); + } + } + + function _changed($orig, $closing) { + $diff = new InlineWordLevelDiff($orig, $closing); + $add = $diff->inline(); + + foreach ($add as $line) + print(''.$line."\n"); + } +} + //Setup VIM: ex: et ts=4 enc=utf-8 : -- cgit v1.2.3