/lib/diff/Renderer.php
https://gitlab.com/ElvisAns/tiki · PHP · 208 lines · 147 code · 27 blank · 34 comment · 15 complexity · 67d75f99e28a93b21a3c4eaee3c553b1 MD5 · raw file
- <?php
- /**
- * A class to render Diffs in different formats.
- *
- * This class renders the diff in classic diff format. It is intended that
- * this class be customized via inheritance, to obtain fancier outputs.
- *
- * $Horde: framework/Text_Diff/Diff/Renderer.php,v 1.5 2004/10/13 09:30:20 jan Exp $
- *
- * @package Text_Diff
- */
- class Text_Diff_Renderer
- {
- /**
- * Number of leading context "lines" to preserve.
- *
- * This should be left at zero for this class, but subclasses may want to
- * set this to other values.
- */
- protected $_leading_context_lines = 0;
- /**
- * Number of trailing context "lines" to preserve.
- *
- * This should be left at zero for this class, but subclasses may want to
- * set this to other values.
- */
- protected $_trailing_context_lines = 0;
- /**
- * Constructor.
- */
- public function __construct($params = [])
- {
- foreach ($params as $param => $value) {
- $v = '_' . $param;
- if (isset($this->$v)) {
- $this->$v = $value;
- }
- }
- }
- /**
- * Renders a diff.
- *
- * @param Text_Diff $diff A Text_Diff object.
- *
- * @return string The formatted output.
- */
- public function render($diff)
- {
- $xi = $yi = 1;
- $block = false;
- $context = [];
- $nlead = $this->_leading_context_lines;
- $ntrail = $this->_trailing_context_lines;
- $this->_startDiff();
- foreach ($diff->getDiff() as $edit) {
- if (is_a($edit, 'Text_Diff_Op_copy')) {
- if (is_array($block)) {
- if (count($edit->orig) <= $nlead + $ntrail) {
- $block[] = $edit;
- } else {
- if ($ntrail) {
- $context = array_slice($edit->orig, 0, $ntrail);
- $block[] = new Text_Diff_Op_copy($context);
- }
- $this->_block(
- $x0,
- $ntrail + $xi - $x0,
- $y0,
- $ntrail + $yi - $y0,
- $block
- );
- $block = false;
- }
- }
- $context = $edit->orig;
- } else {
- if (! is_array($block)) {
- $context = array_slice($context, count($context) - $nlead);
- $x0 = $xi - count($context);
- $y0 = $yi - count($context);
- $block = [];
- if ($context) {
- $block[] = new Text_Diff_Op_copy($context);
- }
- }
- $block[] = $edit;
- }
- if ($edit->orig) {
- $xi += count($edit->orig);
- }
- if ($edit->final) {
- $yi += count($edit->final);
- }
- }
- if (is_array($block)) {
- $this->_block(
- $x0,
- $xi - $x0,
- $y0,
- $yi - $y0,
- $block
- );
- }
- return $this->_endDiff();
- }
- protected function _block($xbeg, $xlen, $ybeg, $ylen, &$edits)
- {
- $this->_startBlock($this->_blockHeader($xbeg, $xlen, $ybeg, $ylen));
- foreach ($edits as $edit) {
- switch (strtolower(get_class($edit))) {
- case 'text_diff_op_copy':
- $this->_context($edit->orig);
- break;
- case 'text_diff_op_add':
- $this->_added($edit->final);
- break;
- case 'text_diff_op_delete':
- $this->_deleted($edit->orig);
- break;
- case 'text_diff_op_change':
- $this->_changed($edit->orig, $edit->final);
- break;
- default:
- trigger_error("Unknown edit type", E_USER_ERROR);
- }
- $this->_endBlock();
- }
- }
- protected function _startDiff()
- {
- ob_start();
- }
- protected function _endDiff()
- {
- $val = ob_get_contents();
- ob_end_clean();
- return $val;
- }
- protected function _blockHeader($xbeg, $xlen, $ybeg, $ylen)
- {
- if ($xlen > 1) {
- $xbeg .= ',' . ($xbeg + $xlen - 1);
- }
- if ($ylen > 1) {
- $ybeg .= ',' . ($ybeg + $ylen - 1);
- }
- return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg;
- }
- protected function _startBlock($header)
- {
- // TODO: What's this output for? It breaks XML pages
- // echo $header . "\n";
- }
- protected function _endBlock()
- {
- }
- protected function _lines($lines, $prefix = '', $suffix = '', $type = '')
- {
- foreach ($lines as $line) {
- echo "$prefix$line$suffix\n";
- }
- }
- protected function _context($lines)
- {
- $this->_lines($lines, ' ');
- }
- protected function _added($lines)
- {
- $this->_lines($lines, '>');
- }
- protected function _deleted($lines)
- {
- $this->_lines($lines, '<');
- }
- protected function _changed($orig, $final)
- {
- $this->_deleted($orig);
- echo "---\n";
- $this->_added($final);
- }
- }