Example #1
0
 /**
  * Renders a diff.
  *
  * @param diff &$diff A diff object.
  *
  * @return string  The formatted output.
  */
 function render(&$diff)
 {
     $xi = $yi = 1;
     $block = false;
     $context = array();
     // Create a new diff object if it is a 3-way diff
     if (is_a($diff, 'diff3')) {
         $diff3 =& $diff;
         $diff_1 = $diff3->get_original();
         $diff_2 = $diff3->merged_output();
         unset($diff3);
         $diff = new diff($diff_1, $diff_2);
     }
     $nlead = $this->_leading_context_lines;
     $ntrail = $this->_trailing_context_lines;
     $output = $this->_start_diff();
     $diffs = $diff->get_diff();
     foreach ($diffs as $i => $edit) {
         // If these are unchanged (copied) lines, and we want to keep leading or trailing context lines, extract them from the copy block.
         if (is_a($edit, 'diff_op_copy')) {
             // Do we have any diff blocks yet?
             if (is_array($block)) {
                 // How many lines to keep as context from the copy block.
                 $keep = $i == sizeof($diffs) - 1 ? $ntrail : $nlead + $ntrail;
                 if (sizeof($edit->orig) <= $keep) {
                     // We have less lines in the block than we want for context => keep the whole block.
                     $block[] = $edit;
                 } else {
                     if ($ntrail) {
                         // Create a new block with as many lines as we need for the trailing context.
                         $context = array_slice($edit->orig, 0, $ntrail);
                         $block[] = new diff_op_copy($context);
                     }
                     $output .= $this->_block($x0, $ntrail + $xi - $x0, $y0, $ntrail + $yi - $y0, $block);
                     $block = false;
                 }
             }
             // Keep the copy block as the context for the next block.
             $context = $edit->orig;
         } else {
             // Don't we have any diff blocks yet?
             if (!is_array($block)) {
                 // Extract context lines from the preceding copy block.
                 $context = array_slice($context, sizeof($context) - $nlead);
                 $x0 = $xi - sizeof($context);
                 $y0 = $yi - sizeof($context);
                 $block = array();
                 if ($context) {
                     $block[] = new diff_op_copy($context);
                 }
             }
             $block[] = $edit;
         }
         $xi += $edit->orig ? sizeof($edit->orig) : 0;
         $yi += $edit->final ? sizeof($edit->final) : 0;
     }
     if (is_array($block)) {
         $output .= $this->_block($x0, $xi - $x0, $y0, $yi - $y0, $block);
     }
     return $output . $this->_end_diff();
 }