Text_Diff
[ class tree: Text_Diff ] [ index: Text_Diff ] [ all elements ]

Source for file Renderer.php

Documentation is available at Renderer.php

  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.  * $Horde: framework/Text_Diff/Diff/Renderer.php,v 1.15 2007/02/18 01:38:32 selsky Exp $
  9.  *
  10.  * @package Text_Diff
  11.  */
  12.  
  13.     /**
  14.      * Number of leading context "lines" to preserve.
  15.      *
  16.      * This should be left at zero for this class, but subclasses may want to
  17.      * set this to other values.
  18.      */
  19.     var $_leading_context_lines = 0;
  20.  
  21.     /**
  22.      * Number of trailing context "lines" to preserve.
  23.      *
  24.      * This should be left at zero for this class, but subclasses may want to
  25.      * set this to other values.
  26.      */
  27.     var $_trailing_context_lines = 0;
  28.  
  29.     /**
  30.      * Constructor.
  31.      */
  32.     function Text_Diff_Renderer($params = array())
  33.     {
  34.         foreach ($params as $param => $value{
  35.             $v '_' $param;
  36.             if (isset($this->$v)) {
  37.                 $this->$v $value;
  38.             }
  39.         }
  40.     }
  41.  
  42.     /**
  43.      * Get any renderer parameters.
  44.      *
  45.      * @return array  All parameters of this renderer object.
  46.      */
  47.     function getParams()
  48.     {
  49.         $params = array();
  50.         foreach (get_object_vars($thisas $k => $v{
  51.             if ($k[0== '_'{
  52.                 $params[substr($k1)$v;
  53.             }
  54.         }
  55.  
  56.         return $params;
  57.     }
  58.  
  59.     /**
  60.      * Renders a diff.
  61.      *
  62.      * @param Text_Diff $diff  A Text_Diff object.
  63.      *
  64.      * @return string  The formatted output.
  65.      */
  66.     function render($diff)
  67.     {
  68.         $xi $yi = 1;
  69.         $block = false;
  70.         $context = array();
  71.  
  72.         $nlead $this->_leading_context_lines;
  73.         $ntrail $this->_trailing_context_lines;
  74.  
  75.         $output $this->_startDiff();
  76.  
  77.         $diffs $diff->getDiff();
  78.         foreach ($diffs as $i => $edit{
  79.             /* If these are unchanged (copied) lines, and we want to keep
  80.              * leading or trailing context lines, extract them from the copy
  81.              * block. */
  82.             if (is_a($edit'Text_Diff_Op_copy')) {
  83.                 /* Do we have any diff blocks yet? */
  84.                 if (is_array($block)) {
  85.                     /* How many lines to keep as context from the copy
  86.                      * block. */
  87.                     $keep $i == count($diffs- 1 ? $ntrail $nlead $ntrail;
  88.                     if (count($edit->orig<= $keep{
  89.                         /* We have less lines in the block than we want for
  90.                          * context => keep the whole block. */
  91.                         $block[$edit;
  92.                     else {
  93.                         if ($ntrail{
  94.                             /* Create a new block with as many lines as we need
  95.                              * for the trailing context. */
  96.                             $context array_slice($edit->orig0$ntrail);
  97.                             $block[&new Text_Diff_Op_copy($context);
  98.                         }
  99.                         /* @todo */
  100.                         $output .= $this->_block($x0$ntrail $xi $x0,
  101.                                                  $y0$ntrail $yi $y0,
  102.                                                  $block);
  103.                         $block = false;
  104.                     }
  105.                 }
  106.                 /* Keep the copy block as the context for the next block. */
  107.                 $context $edit->orig;
  108.             else {
  109.                 /* Don't we have any diff blocks yet? */
  110.                 if (!is_array($block)) {
  111.                     /* Extract context lines from the preceding copy block. */
  112.                     $context array_slice($contextcount($context$nlead);
  113.                     $x0 $xi count($context);
  114.                     $y0 $yi count($context);
  115.                     $block = array();
  116.                     if ($context{
  117.                         $block[&new Text_Diff_Op_copy($context);
  118.                     }
  119.                 }
  120.                 $block[$edit;
  121.             }
  122.  
  123.             if ($edit->orig{
  124.                 $xi += count($edit->orig);
  125.             }
  126.             if ($edit->final{
  127.                 $yi += count($edit->final);
  128.             }
  129.         }
  130.  
  131.         if (is_array($block)) {
  132.             $output .= $this->_block($x0$xi $x0,
  133.                                      $y0$yi $y0,
  134.                                      $block);
  135.         }
  136.  
  137.         return $output $this->_endDiff();
  138.     }
  139.  
  140.     function _block($xbeg$xlen$ybeg$ylen&$edits)
  141.     {
  142.         $output $this->_startBlock($this->_blockHeader($xbeg$xlen$ybeg$ylen));
  143.  
  144.         foreach ($edits as $edit{
  145.             switch (strtolower(get_class($edit))) {
  146.             case 'text_diff_op_copy':
  147.                 $output .= $this->_context($edit->orig);
  148.                 break;
  149.  
  150.             case 'text_diff_op_add':
  151.                 $output .= $this->_added($edit->final);
  152.                 break;
  153.  
  154.             case 'text_diff_op_delete':
  155.                 $output .= $this->_deleted($edit->orig);
  156.                 break;
  157.  
  158.             case 'text_diff_op_change':
  159.                 $output .= $this->_changed($edit->orig$edit->final);
  160.                 break;
  161.             }
  162.         }
  163.  
  164.         return $output $this->_endBlock();
  165.     }
  166.  
  167.     function _startDiff()
  168.     {
  169.         return '';
  170.     }
  171.  
  172.     function _endDiff()
  173.     {
  174.         return '';
  175.     }
  176.  
  177.     function _blockHeader($xbeg$xlen$ybeg$ylen)
  178.     {
  179.         if ($xlen > 1{
  180.             $xbeg .= ',' ($xbeg $xlen - 1);
  181.         }
  182.         if ($ylen > 1{
  183.             $ybeg .= ',' ($ybeg $ylen - 1);
  184.         }
  185.  
  186.         return $xbeg ($xlen ($ylen 'c' 'd''a'$ybeg;
  187.     }
  188.  
  189.     function _startBlock($header)
  190.     {
  191.         return $header "\n";
  192.     }
  193.  
  194.     function _endBlock()
  195.     {
  196.         return '';
  197.     }
  198.  
  199.     function _lines($lines$prefix ' ')
  200.     {
  201.         return $prefix implode("\n$prefix"$lines"\n";
  202.     }
  203.  
  204.     function _context($lines)
  205.     {
  206.         return $this->_lines($lines'  ');
  207.     }
  208.  
  209.     function _added($lines)
  210.     {
  211.         return $this->_lines($lines'> ');
  212.     }
  213.  
  214.     function _deleted($lines)
  215.     {
  216.         return $this->_lines($lines'< ');
  217.     }
  218.  
  219.     function _changed($orig$final)
  220.     {
  221.         return $this->_deleted($orig"---\n" $this->_added($final);
  222.     }
  223.  
  224. }

Documentation generated on Mon, 11 Mar 2019 15:09:50 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.