Ticket #9467: textdiff.new.version.patch
File textdiff.new.version.patch, 18.8 KB (added by , 15 years ago) |
---|
-
Diff.php
6 6 * The original PHP version of this code was written by Geoffrey T. Dairiki 7 7 * <dairiki@dairiki.org>, and is used/adapted with his permission. 8 8 * 9 * $Horde: framework/Text_Diff/Diff.php,v 1.26 2008/01/04 10:07:49 jan Exp $10 *11 9 * Copyright 2004 Geoffrey T. Dairiki <dairiki@dairiki.org> 12 * Copyright 2004-20 08The Horde Project (http://www.horde.org/)10 * Copyright 2004-2010 The Horde Project (http://www.horde.org/) 13 11 * 14 12 * See the enclosed file COPYING for license information (LGPL). If you did 15 13 * not receive this file, see http://opensource.org/licenses/lgpl-license.php. … … 49 47 $engine = basename($engine); 50 48 } 51 49 52 // WP #739150 // WP path fix 53 51 require_once dirname(__FILE__).'/Diff/Engine/' . $engine . '.php'; 54 52 $class = 'Text_Diff_Engine_' . $engine; 55 53 $diff_engine = new $class(); … … 66 64 } 67 65 68 66 /** 67 * returns the number of new (added) lines in a given diff. 68 * 69 * @since Text_Diff 1.1.0 70 * 71 * @return integer The number of new lines 72 */ 73 function countAddedLines() 74 { 75 $count = 0; 76 foreach ($this->_edits as $edit) { 77 if (is_a($edit, 'Text_Diff_Op_add') || 78 is_a($edit, 'Text_Diff_Op_change')) { 79 $count += $edit->nfinal(); 80 } 81 } 82 return $count; 83 } 84 85 /** 86 * Returns the number of deleted (removed) lines in a given diff. 87 * 88 * @since Text_Diff 1.1.0 89 * 90 * @return integer The number of deleted lines 91 */ 92 function countDeletedLines() 93 { 94 $count = 0; 95 foreach ($this->_edits as $edit) { 96 if (is_a($edit, 'Text_Diff_Op_delete') || 97 is_a($edit, 'Text_Diff_Op_change')) { 98 $count += $edit->norig(); 99 } 100 } 101 return $count; 102 } 103 104 /** 69 105 * Computes a reversed diff. 70 106 * 71 107 * Example: … … 341 377 342 378 function &reverse() 343 379 { 344 $reverse = &new Text_Diff_Op_copy($this->final, $this->orig);380 $reverse = new Text_Diff_Op_copy($this->final, $this->orig); 345 381 return $reverse; 346 382 } 347 383 … … 363 399 364 400 function &reverse() 365 401 { 366 $reverse = &new Text_Diff_Op_add($this->orig);402 $reverse = new Text_Diff_Op_add($this->orig); 367 403 return $reverse; 368 404 } 369 405 … … 385 421 386 422 function &reverse() 387 423 { 388 $reverse = &new Text_Diff_Op_delete($this->final);424 $reverse = new Text_Diff_Op_delete($this->final); 389 425 return $reverse; 390 426 } 391 427 … … 407 443 408 444 function &reverse() 409 445 { 410 $reverse = &new Text_Diff_Op_change($this->final, $this->orig);446 $reverse = new Text_Diff_Op_change($this->final, $this->orig); 411 447 return $reverse; 412 448 } 413 449 -
Diff/Engine/native.php
1 1 <?php 2 2 /** 3 * $Horde: framework/Text_Diff/Diff/Engine/native.php,v 1.10 2008/01/04 10:27:53 jan Exp $3 * Class used internally by Text_Diff to actually compute the diffs. 4 4 * 5 * Class used internally by Text_Diff to actually compute the diffs. This 6 * class is implemented using native PHP code. 5 * This class is implemented using native PHP code. 7 6 * 8 7 * The algorithm used here is mostly lifted from the perl module 9 8 * Algorithm::Diff (version 1.06) by Ned Konz, which is available at: … … 19 18 * Geoffrey T. Dairiki <dairiki@dairiki.org>. The original PHP version of this 20 19 * code was written by him, and is used/adapted with his permission. 21 20 * 22 * Copyright 2004-20 08The Horde Project (http://www.horde.org/)21 * Copyright 2004-2010 The Horde Project (http://www.horde.org/) 23 22 * 24 23 * See the enclosed file COPYING for license information (LGPL). If you did 25 24 * not receive this file, see http://opensource.org/licenses/lgpl-license.php. … … 105 104 ++$yi; 106 105 } 107 106 if ($copy) { 108 $edits[] = &new Text_Diff_Op_copy($copy);107 $edits[] = new Text_Diff_Op_copy($copy); 109 108 } 110 109 111 110 // Find deletes & adds. … … 120 119 } 121 120 122 121 if ($delete && $add) { 123 $edits[] = &new Text_Diff_Op_change($delete, $add);122 $edits[] = new Text_Diff_Op_change($delete, $add); 124 123 } elseif ($delete) { 125 $edits[] = &new Text_Diff_Op_delete($delete);124 $edits[] = new Text_Diff_Op_delete($delete); 126 125 } elseif ($add) { 127 $edits[] = &new Text_Diff_Op_add($add);126 $edits[] = new Text_Diff_Op_add($add); 128 127 } 129 128 } 130 129 -
Diff/Engine/shell.php
5 5 * This class uses the Unix `diff` program via shell_exec to compute the 6 6 * differences between the two input arrays. 7 7 * 8 * $Horde: framework/Text_Diff/Diff/Engine/shell.php,v 1.8 2008/01/04 10:07:50 jan Exp $8 * Copyright 2007-2010 The Horde Project (http://www.horde.org/) 9 9 * 10 * Copyright 2007-2008 The Horde Project (http://www.horde.org/)11 *12 10 * See the enclosed file COPYING for license information (LGPL). If you did 13 11 * not receive this file, see http://opensource.org/licenses/lgpl-license.php. 14 12 * -
Diff/Engine/string.php
10 10 * echo $renderer->render($diff); 11 11 * </code> 12 12 * 13 * $Horde: framework/Text_Diff/Diff/Engine/string.php,v 1.7 2008/01/04 10:07:50 jan Exp $14 *15 13 * Copyright 2005 Örjan Persson <o@42mm.org> 16 * Copyright 2005-20 08The Horde Project (http://www.horde.org/)14 * Copyright 2005-2010 The Horde Project (http://www.horde.org/) 17 15 * 18 16 * See the enclosed file COPYING for license information (LGPL). If you did 19 17 * not receive this file, see http://opensource.org/licenses/lgpl-license.php. … … 39 37 */ 40 38 function diff($diff, $mode = 'autodetect') 41 39 { 40 // Detect line breaks. 41 $lnbr = "\n"; 42 if (strpos($diff, "\r\n") !== false) { 43 $lnbr = "\r\n"; 44 } elseif (strpos($diff, "\r") !== false) { 45 $lnbr = "\r"; 46 } 47 48 // Make sure we have a line break at the EOF. 49 if (substr($diff, -strlen($lnbr)) != $lnbr) { 50 $diff .= $lnbr; 51 } 52 42 53 if ($mode != 'autodetect' && $mode != 'context' && $mode != 'unified') { 43 54 return PEAR::raiseError('Type of diff is unsupported'); 44 55 } … … 48 59 $unified = strpos($diff, '---'); 49 60 if ($context === $unified) { 50 61 return PEAR::raiseError('Type of diff could not be detected'); 51 } elseif ($context === false || $ context=== false) {62 } elseif ($context === false || $unified === false) { 52 63 $mode = $context !== false ? 'context' : 'unified'; 53 64 } else { 54 65 $mode = $context < $unified ? 'context' : 'unified'; 55 66 } 56 67 } 57 68 58 // split by new line and remove the diff header 59 $diff = explode("\n", $diff); 60 array_shift($diff); 61 array_shift($diff); 69 // Split by new line and remove the diff header, if there is one. 70 $diff = explode($lnbr, $diff); 71 if (($mode == 'context' && strpos($diff[0], '***') === 0) || 72 ($mode == 'unified' && strpos($diff[0], '---') === 0)) { 73 array_shift($diff); 74 array_shift($diff); 75 } 62 76 63 77 if ($mode == 'context') { 64 78 return $this->parseContextDiff($diff); … … 85 99 do { 86 100 $diff1[] = substr($diff[$i], 1); 87 101 } while (++$i < $end && substr($diff[$i], 0, 1) == ' '); 88 $edits[] = &new Text_Diff_Op_copy($diff1);102 $edits[] = new Text_Diff_Op_copy($diff1); 89 103 break; 90 104 91 105 case '+': … … 93 107 do { 94 108 $diff1[] = substr($diff[$i], 1); 95 109 } while (++$i < $end && substr($diff[$i], 0, 1) == '+'); 96 $edits[] = &new Text_Diff_Op_add($diff1);110 $edits[] = new Text_Diff_Op_add($diff1); 97 111 break; 98 112 99 113 case '-': … … 107 121 $diff2[] = substr($diff[$i++], 1); 108 122 } 109 123 if (count($diff2) == 0) { 110 $edits[] = &new Text_Diff_Op_delete($diff1);124 $edits[] = new Text_Diff_Op_delete($diff1); 111 125 } else { 112 $edits[] = &new Text_Diff_Op_change($diff1, $diff2);126 $edits[] = new Text_Diff_Op_change($diff1, $diff2); 113 127 } 114 128 break; 115 129 … … 175 189 $array[] = substr($diff[$j++], 2); 176 190 } 177 191 if (count($array) > 0) { 178 $edits[] = &new Text_Diff_Op_copy($array);192 $edits[] = new Text_Diff_Op_copy($array); 179 193 } 180 194 181 195 if ($i < $max_i) { … … 189 203 $diff2[] = substr($diff[$j++], 2); 190 204 } 191 205 } while (++$i < $max_i && substr($diff[$i], 0, 1) == '!'); 192 $edits[] = &new Text_Diff_Op_change($diff1, $diff2);206 $edits[] = new Text_Diff_Op_change($diff1, $diff2); 193 207 break; 194 208 195 209 case '+': 196 210 do { 197 211 $diff1[] = substr($diff[$i], 2); 198 212 } while (++$i < $max_i && substr($diff[$i], 0, 1) == '+'); 199 $edits[] = &new Text_Diff_Op_add($diff1);213 $edits[] = new Text_Diff_Op_add($diff1); 200 214 break; 201 215 202 216 case '-': 203 217 do { 204 218 $diff1[] = substr($diff[$i], 2); 205 219 } while (++$i < $max_i && substr($diff[$i], 0, 1) == '-'); 206 $edits[] = &new Text_Diff_Op_delete($diff1);220 $edits[] = new Text_Diff_Op_delete($diff1); 207 221 break; 208 222 } 209 223 } … … 215 229 do { 216 230 $diff2[] = substr($diff[$j++], 2); 217 231 } while ($j < $max_j && substr($diff[$j], 0, 1) == '+'); 218 $edits[] = &new Text_Diff_Op_add($diff2);232 $edits[] = new Text_Diff_Op_add($diff2); 219 233 break; 220 234 221 235 case '-': 222 236 do { 223 237 $diff2[] = substr($diff[$j++], 2); 224 238 } while ($j < $max_j && substr($diff[$j], 0, 1) == '-'); 225 $edits[] = &new Text_Diff_Op_delete($diff2);239 $edits[] = new Text_Diff_Op_delete($diff2); 226 240 break; 227 241 } 228 242 } -
Diff/Engine/xdiff.php
5 5 * This class uses the xdiff PECL package (http://pecl.php.net/package/xdiff) 6 6 * to compute the differences between the two input arrays. 7 7 * 8 * $Horde: framework/Text_Diff/Diff/Engine/xdiff.php,v 1.6 2008/01/04 10:07:50 jan Exp $8 * Copyright 2004-2010 The Horde Project (http://www.horde.org/) 9 9 * 10 * Copyright 2004-2008 The Horde Project (http://www.horde.org/)11 *12 10 * See the enclosed file COPYING for license information (LGPL). If you did 13 11 * not receive this file, see http://opensource.org/licenses/lgpl-license.php. 14 12 * … … 42 40 * valid, albeit a little less descriptive and efficient. */ 43 41 $edits = array(); 44 42 foreach ($diff as $line) { 43 if (!strlen($line)) { 44 continue; 45 } 45 46 switch ($line[0]) { 46 47 case ' ': 47 $edits[] = &new Text_Diff_Op_copy(array(substr($line, 1)));48 $edits[] = new Text_Diff_Op_copy(array(substr($line, 1))); 48 49 break; 49 50 50 51 case '+': 51 $edits[] = &new Text_Diff_Op_add(array(substr($line, 1)));52 $edits[] = new Text_Diff_Op_add(array(substr($line, 1))); 52 53 break; 53 54 54 55 case '-': 55 $edits[] = &new Text_Diff_Op_delete(array(substr($line, 1)));56 $edits[] = new Text_Diff_Op_delete(array(substr($line, 1))); 56 57 break; 57 58 } 58 59 } -
Diff/Renderer.php
5 5 * This class renders the diff in classic diff format. It is intended that 6 6 * this class be customized via inheritance, to obtain fancier outputs. 7 7 * 8 * $Horde: framework/Text_Diff/Diff/Renderer.php,v 1.21 2008/01/04 10:07:50 jan Exp $8 * Copyright 2004-2010 The Horde Project (http://www.horde.org/) 9 9 * 10 * Copyright 2004-2008 The Horde Project (http://www.horde.org/)11 *12 10 * See the enclosed file COPYING for license information (LGPL). If you did 13 11 * not receive this file, see http://opensource.org/licenses/lgpl-license.php. 14 12 * … … 100 98 /* Create a new block with as many lines as we need 101 99 * for the trailing context. */ 102 100 $context = array_slice($edit->orig, 0, $ntrail); 103 $block[] = &new Text_Diff_Op_copy($context);101 $block[] = new Text_Diff_Op_copy($context); 104 102 } 105 103 /* @todo */ 106 104 $output .= $this->_block($x0, $ntrail + $xi - $x0, … … 120 118 $y0 = $yi - count($context); 121 119 $block = array(); 122 120 if ($context) { 123 $block[] = &new Text_Diff_Op_copy($context);121 $block[] = new Text_Diff_Op_copy($context); 124 122 } 125 123 } 126 124 $block[] = $edit; -
Diff/Renderer/inline.php
2 2 /** 3 3 * "Inline" diff renderer. 4 4 * 5 * $Horde: framework/Text_Diff/Diff/Renderer/inline.php,v 1.21 2008/01/04 10:07:51 jan Exp $5 * Copyright 2004-2010 The Horde Project (http://www.horde.org/) 6 6 * 7 * Copyright 2004-2008 The Horde Project (http://www.horde.org/)8 *9 7 * See the enclosed file COPYING for license information (LGPL). If you did 10 8 * not receive this file, see http://opensource.org/licenses/lgpl-license.php. 11 9 * … … 15 13 16 14 /** Text_Diff_Renderer */ 17 15 18 // WP #739116 // WP path fix 19 17 require_once dirname(dirname(__FILE__)) . '/Renderer.php'; 20 18 21 19 /** … … 30 28 31 29 /** 32 30 * Number of leading context "lines" to preserve. 31 * 32 * @var integer 33 33 */ 34 34 var $_leading_context_lines = 10000; 35 35 36 36 /** 37 37 * Number of trailing context "lines" to preserve. 38 * 39 * @var integer 38 40 */ 39 41 var $_trailing_context_lines = 10000; 40 42 41 43 /** 42 44 * Prefix for inserted text. 45 * 46 * @var string 43 47 */ 44 48 var $_ins_prefix = '<ins>'; 45 49 46 50 /** 47 51 * Suffix for inserted text. 52 * 53 * @var string 48 54 */ 49 55 var $_ins_suffix = '</ins>'; 50 56 51 57 /** 52 58 * Prefix for deleted text. 59 * 60 * @var string 53 61 */ 54 62 var $_del_prefix = '<del>'; 55 63 56 64 /** 57 65 * Suffix for deleted text. 66 * 67 * @var string 58 68 */ 59 69 var $_del_suffix = '</del>'; 60 70 61 71 /** 62 72 * Header for each change block. 73 * 74 * @var string 63 75 */ 64 76 var $_block_header = ''; 65 77 66 78 /** 79 * Whether to split down to character-level. 80 * 81 * @var boolean 82 */ 83 var $_split_characters = false; 84 85 /** 67 86 * What are we currently splitting on? Used to recurse to show word-level 68 * changes. 87 * or character-level changes. 88 * 89 * @var string 69 90 */ 70 91 var $_split_level = 'lines'; 71 92 … … 85 106 array_walk($lines, array(&$this, '_encode')); 86 107 } 87 108 88 if ($this->_split_level == 'words') { 109 if ($this->_split_level == 'lines') { 110 return implode("\n", $lines) . "\n"; 111 } else { 89 112 return implode('', $lines); 90 } else {91 return implode("\n", $lines) . "\n";92 113 } 93 114 } 94 115 … … 110 131 111 132 function _changed($orig, $final) 112 133 { 113 /* If we've already split on words, don't try to do so again - just 114 * display. */ 134 /* If we've already split on characters, just display. */ 135 if ($this->_split_level == 'characters') { 136 return $this->_deleted($orig) 137 . $this->_added($final); 138 } 139 140 /* If we've already split on words, just display. */ 115 141 if ($this->_split_level == 'words') { 116 142 $prefix = ''; 117 143 while ($orig[0] !== false && $final[0] !== false && … … 130 156 /* Non-printing newline marker. */ 131 157 $nl = "\0"; 132 158 133 /* We want to split on word boundaries, but we need to 134 * preserve whitespace as well. Therefore we split on words, 135 * but include all blocks of whitespace in the wordlist. */ 136 $diff = new Text_Diff($this->_splitOnWords($text1, $nl), 137 $this->_splitOnWords($text2, $nl)); 159 if ($this->_split_characters) { 160 $diff = new Text_Diff('native', 161 array(preg_split('//', $text1), 162 preg_split('//', $text2))); 163 } else { 164 /* We want to split on word boundaries, but we need to preserve 165 * whitespace as well. Therefore we split on words, but include 166 * all blocks of whitespace in the wordlist. */ 167 $diff = new Text_Diff('native', 168 array($this->_splitOnWords($text1, $nl), 169 $this->_splitOnWords($text2, $nl))); 170 } 138 171 139 172 /* Get the diff in inline format. */ 140 $renderer = new Text_Diff_Renderer_inline(array_merge($this->getParams(), 141 array('split_level' => 'words'))); 173 $renderer = new Text_Diff_Renderer_inline 174 (array_merge($this->getParams(), 175 array('split_level' => $this->_split_characters ? 'characters' : 'words'))); 142 176 143 177 /* Run the diff and get the output. */ 144 178 return str_replace($nl, "\n", $renderer->render($diff)) . "\n";