Go to the documentation of this file.00001 <?php
00012 class Text_Diff_Renderer {
00013
00020 public $_leading_context_lines = 0;
00021
00028 public $_trailing_context_lines = 0;
00029
00033 function Text_Diff_Renderer($params = array())
00034 {
00035 foreach ($params as $param => $value) {
00036 $v = '_' . $param;
00037 if (isset($this->$v)) {
00038 $this->$v = $value;
00039 }
00040 }
00041 }
00042
00048 function getParams()
00049 {
00050 $params = array();
00051 foreach (get_object_vars($this) as $k => $v) {
00052 if ($k{0} == '_') {
00053 $params[substr($k, 1)] = $v;
00054 }
00055 }
00056
00057 return $params;
00058 }
00059
00067 function render($diff)
00068 {
00069 $xi = $yi = 1;
00070 $block = false;
00071 $context = array();
00072
00073 $nlead = $this->_leading_context_lines;
00074 $ntrail = $this->_trailing_context_lines;
00075
00076 $output = $this->_startDiff();
00077
00078 foreach ($diff->getDiff() as $edit) {
00079 if ($edit instanceof Text_Diff_Op_copy) {
00080 if (is_array($block)) {
00081 if (count($edit->orig) <= $nlead + $ntrail) {
00082 $block[] = $edit;
00083 } else {
00084 if ($ntrail) {
00085 $context = array_slice($edit->orig, 0, $ntrail);
00086 $block[] = new Text_Diff_Op_copy($context);
00087 }
00088 $output .= $this->_block($x0, $ntrail + $xi - $x0,
00089 $y0, $ntrail + $yi - $y0,
00090 $block);
00091 $block = false;
00092 }
00093 }
00094 $context = $edit->orig;
00095 } else {
00096 if (!is_array($block)) {
00097 $context = array_slice($context, count($context) - $nlead);
00098 $x0 = $xi - count($context);
00099 $y0 = $yi - count($context);
00100 $block = array();
00101 if ($context) {
00102 $block[] = new Text_Diff_Op_copy($context);
00103 }
00104 }
00105 $block[] = $edit;
00106 }
00107
00108 if ($edit->orig) {
00109 $xi += count($edit->orig);
00110 }
00111 if ($edit->final) {
00112 $yi += count($edit->final);
00113 }
00114 }
00115
00116 if (is_array($block)) {
00117 $output .= $this->_block($x0, $xi - $x0,
00118 $y0, $yi - $y0,
00119 $block);
00120 }
00121
00122 return $output . $this->_endDiff();
00123 }
00124
00125 function _block($xbeg, $xlen, $ybeg, $ylen, &$edits)
00126 {
00127 $output = $this->_startBlock($this->_blockHeader($xbeg, $xlen, $ybeg, $ylen));
00128
00129 foreach ($edits as $edit) {
00130 switch (strtolower(get_class($edit))) {
00131 case 'text_diff_op_copy':
00132 $output .= $this->_context($edit->orig);
00133 break;
00134
00135 case 'text_diff_op_add':
00136 $output .= $this->_added($edit->final);
00137 break;
00138
00139 case 'text_diff_op_delete':
00140 $output .= $this->_deleted($edit->orig);
00141 break;
00142
00143 case 'text_diff_op_change':
00144 $output .= $this->_changed($edit->orig, $edit->final);
00145 break;
00146 }
00147 }
00148
00149 return $output . $this->_endBlock();
00150 }
00151
00152 function _startDiff()
00153 {
00154 return '';
00155 }
00156
00157 function _endDiff()
00158 {
00159 return '';
00160 }
00161
00162 function _blockHeader($xbeg, $xlen, $ybeg, $ylen)
00163 {
00164 if ($xlen > 1) {
00165 $xbeg .= ',' . ($xbeg + $xlen - 1);
00166 }
00167 if ($ylen > 1) {
00168 $ybeg .= ',' . ($ybeg + $ylen - 1);
00169 }
00170
00171 return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg;
00172 }
00173
00174 function _startBlock($header)
00175 {
00176 return $header . "\n";
00177 }
00178
00179 function _endBlock()
00180 {
00181 return '';
00182 }
00183
00184 function _lines($lines, $prefix = ' ')
00185 {
00186 return $prefix . implode("\n$prefix", $lines) . "\n";
00187 }
00188
00189 function _context($lines)
00190 {
00191 return $this->_lines($lines);
00192 }
00193
00194 function _added($lines)
00195 {
00196 return $this->_lines($lines, '>');
00197 }
00198
00199 function _deleted($lines)
00200 {
00201 return $this->_lines($lines, '<');
00202 }
00203
00204 function _changed($orig, $final)
00205 {
00206 return $this->_deleted($orig) . "---\n" . $this->_added($final);
00207 }
00208
00209 }