Text_Diff_Renderer

A class to render Diffs in different formats.

Defined (1)

The class is defined in the following location(s).

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