[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * A class to render Diffs in different formats. 4 * 5 * This class renders the diff in classic diff format. It is intended that 6 * this class be customized via inheritance, to obtain fancier outputs. 7 * 8 * Copyright 2004-2010 The Horde Project (http://www.horde.org/) 9 * 10 * See the enclosed file COPYING for license information (LGPL). If you did 11 * not receive this file, see http://opensource.org/licenses/lgpl-license.php. 12 * 13 * @package Text_Diff 14 */ 15 class Text_Diff_Renderer { 16 17 /** 18 * Number of leading context "lines" to preserve. 19 * 20 * This should be left at zero for this class, but subclasses may want to 21 * set this to other values. 22 */ 23 var $_leading_context_lines = 0; 24 25 /** 26 * Number of trailing context "lines" to preserve. 27 * 28 * This should be left at zero for this class, but subclasses may want to 29 * set this to other values. 30 */ 31 var $_trailing_context_lines = 0; 32 33 /** 34 * Constructor. 35 */ 36 function __construct( $params = array() ) 37 { 38 foreach ($params as $param => $value) { 39 $v = '_' . $param; 40 if (isset($this->$v)) { 41 $this->$v = $value; 42 } 43 } 44 } 45 46 /** 47 * PHP4 constructor. 48 */ 49 public function Text_Diff_Renderer( $params = array() ) { 50 self::__construct( $params ); 51 } 52 53 /** 54 * Get any renderer parameters. 55 * 56 * @return array All parameters of this renderer object. 57 */ 58 function getParams() 59 { 60 $params = array(); 61 foreach (get_object_vars($this) as $k => $v) { 62 if ($k[0] == '_') { 63 $params[substr($k, 1)] = $v; 64 } 65 } 66 67 return $params; 68 } 69 70 /** 71 * Renders a diff. 72 * 73 * @param Text_Diff $diff A Text_Diff object. 74 * 75 * @return string The formatted output. 76 */ 77 function render($diff) 78 { 79 $xi = $yi = 1; 80 $block = false; 81 $context = array(); 82 83 $nlead = $this->_leading_context_lines; 84 $ntrail = $this->_trailing_context_lines; 85 86 $output = $this->_startDiff(); 87 88 $diffs = $diff->getDiff(); 89 foreach ($diffs as $i => $edit) { 90 /* If these are unchanged (copied) lines, and we want to keep 91 * leading or trailing context lines, extract them from the copy 92 * block. */ 93 if (is_a($edit, 'Text_Diff_Op_copy')) { 94 /* Do we have any diff blocks yet? */ 95 if (is_array($block)) { 96 /* How many lines to keep as context from the copy 97 * block. */ 98 $keep = $i == count($diffs) - 1 ? $ntrail : $nlead + $ntrail; 99 if (count($edit->orig) <= $keep) { 100 /* We have less lines in the block than we want for 101 * context => keep the whole block. */ 102 $block[] = $edit; 103 } else { 104 if ($ntrail) { 105 /* Create a new block with as many lines as we need 106 * for the trailing context. */ 107 $context = array_slice($edit->orig, 0, $ntrail); 108 $block[] = new Text_Diff_Op_copy($context); 109 } 110 /* @todo */ 111 $output .= $this->_block($x0, $ntrail + $xi - $x0, 112 $y0, $ntrail + $yi - $y0, 113 $block); 114 $block = false; 115 } 116 } 117 /* Keep the copy block as the context for the next block. */ 118 $context = $edit->orig; 119 } else { 120 /* Don't we have any diff blocks yet? */ 121 if (!is_array($block)) { 122 /* Extract context lines from the preceding copy block. */ 123 $context = array_slice($context, count($context) - $nlead); 124 $x0 = $xi - count($context); 125 $y0 = $yi - count($context); 126 $block = array(); 127 if ($context) { 128 $block[] = new Text_Diff_Op_copy($context); 129 } 130 } 131 $block[] = $edit; 132 } 133 134 if ($edit->orig) { 135 $xi += count($edit->orig); 136 } 137 if ($edit->final) { 138 $yi += count($edit->final); 139 } 140 } 141 142 if (is_array($block)) { 143 $output .= $this->_block($x0, $xi - $x0, 144 $y0, $yi - $y0, 145 $block); 146 } 147 148 return $output . $this->_endDiff(); 149 } 150 151 function _block($xbeg, $xlen, $ybeg, $ylen, &$edits) 152 { 153 $output = $this->_startBlock($this->_blockHeader($xbeg, $xlen, $ybeg, $ylen)); 154 155 foreach ($edits as $edit) { 156 switch (strtolower(get_class($edit))) { 157 case 'text_diff_op_copy': 158 $output .= $this->_context($edit->orig); 159 break; 160 161 case 'text_diff_op_add': 162 $output .= $this->_added($edit->final); 163 break; 164 165 case 'text_diff_op_delete': 166 $output .= $this->_deleted($edit->orig); 167 break; 168 169 case 'text_diff_op_change': 170 $output .= $this->_changed($edit->orig, $edit->final); 171 break; 172 } 173 } 174 175 return $output . $this->_endBlock(); 176 } 177 178 function _startDiff() 179 { 180 return ''; 181 } 182 183 function _endDiff() 184 { 185 return ''; 186 } 187 188 function _blockHeader($xbeg, $xlen, $ybeg, $ylen) 189 { 190 if ($xlen > 1) { 191 $xbeg .= ',' . ($xbeg + $xlen - 1); 192 } 193 if ($ylen > 1) { 194 $ybeg .= ',' . ($ybeg + $ylen - 1); 195 } 196 197 // this matches the GNU Diff behaviour 198 if ($xlen && !$ylen) { 199 $ybeg--; 200 } elseif (!$xlen) { 201 $xbeg--; 202 } 203 204 return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg; 205 } 206 207 function _startBlock($header) 208 { 209 return $header . "\n"; 210 } 211 212 function _endBlock() 213 { 214 return ''; 215 } 216 217 function _lines($lines, $prefix = ' ') 218 { 219 return $prefix . implode("\n$prefix", $lines) . "\n"; 220 } 221 222 function _context($lines) 223 { 224 return $this->_lines($lines, ' '); 225 } 226 227 function _added($lines) 228 { 229 return $this->_lines($lines, '> '); 230 } 231 232 function _deleted($lines) 233 { 234 return $this->_lines($lines, '< '); 235 } 236 237 function _changed($orig, $final) 238 { 239 return $this->_deleted($orig) . "---\n" . $this->_added($final); 240 } 241 242 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Nov 21 01:00:03 2024 | Cross-referenced by PHPXref 0.7.1 |