raw
mp-wp_genesis           1 <?php
mp-wp_genesis 2 /**
mp-wp_genesis 3 * "Inline" diff renderer.
mp-wp_genesis 4 *
mp-wp_genesis 5 * $Horde: framework/Text_Diff/Diff/Renderer/inline.php,v 1.21 2008/01/04 10:07:51 jan Exp $
mp-wp_genesis 6 *
mp-wp_genesis 7 * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
mp-wp_genesis 8 *
mp-wp_genesis 9 * See the enclosed file COPYING for license information (LGPL). If you did
mp-wp_genesis 10 * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
mp-wp_genesis 11 *
mp-wp_genesis 12 * @author Ciprian Popovici
mp-wp_genesis 13 * @package Text_Diff
mp-wp_genesis 14 */
mp-wp_genesis 15
mp-wp_genesis 16 /** Text_Diff_Renderer */
mp-wp_genesis 17
mp-wp_genesis 18 // WP #7391
mp-wp_genesis 19 require_once dirname(dirname(__FILE__)) . '/Renderer.php';
mp-wp_genesis 20
mp-wp_genesis 21 /**
mp-wp_genesis 22 * "Inline" diff renderer.
mp-wp_genesis 23 *
mp-wp_genesis 24 * This class renders diffs in the Wiki-style "inline" format.
mp-wp_genesis 25 *
mp-wp_genesis 26 * @author Ciprian Popovici
mp-wp_genesis 27 * @package Text_Diff
mp-wp_genesis 28 */
mp-wp_genesis 29 class Text_Diff_Renderer_inline extends Text_Diff_Renderer {
mp-wp_genesis 30
mp-wp_genesis 31 /**
mp-wp_genesis 32 * Number of leading context "lines" to preserve.
mp-wp_genesis 33 */
mp-wp_genesis 34 var $_leading_context_lines = 10000;
mp-wp_genesis 35
mp-wp_genesis 36 /**
mp-wp_genesis 37 * Number of trailing context "lines" to preserve.
mp-wp_genesis 38 */
mp-wp_genesis 39 var $_trailing_context_lines = 10000;
mp-wp_genesis 40
mp-wp_genesis 41 /**
mp-wp_genesis 42 * Prefix for inserted text.
mp-wp_genesis 43 */
mp-wp_genesis 44 var $_ins_prefix = '<ins>';
mp-wp_genesis 45
mp-wp_genesis 46 /**
mp-wp_genesis 47 * Suffix for inserted text.
mp-wp_genesis 48 */
mp-wp_genesis 49 var $_ins_suffix = '</ins>';
mp-wp_genesis 50
mp-wp_genesis 51 /**
mp-wp_genesis 52 * Prefix for deleted text.
mp-wp_genesis 53 */
mp-wp_genesis 54 var $_del_prefix = '<del>';
mp-wp_genesis 55
mp-wp_genesis 56 /**
mp-wp_genesis 57 * Suffix for deleted text.
mp-wp_genesis 58 */
mp-wp_genesis 59 var $_del_suffix = '</del>';
mp-wp_genesis 60
mp-wp_genesis 61 /**
mp-wp_genesis 62 * Header for each change block.
mp-wp_genesis 63 */
mp-wp_genesis 64 var $_block_header = '';
mp-wp_genesis 65
mp-wp_genesis 66 /**
mp-wp_genesis 67 * What are we currently splitting on? Used to recurse to show word-level
mp-wp_genesis 68 * changes.
mp-wp_genesis 69 */
mp-wp_genesis 70 var $_split_level = 'lines';
mp-wp_genesis 71
mp-wp_genesis 72 function _blockHeader($xbeg, $xlen, $ybeg, $ylen)
mp-wp_genesis 73 {
mp-wp_genesis 74 return $this->_block_header;
mp-wp_genesis 75 }
mp-wp_genesis 76
mp-wp_genesis 77 function _startBlock($header)
mp-wp_genesis 78 {
mp-wp_genesis 79 return $header;
mp-wp_genesis 80 }
mp-wp_genesis 81
mp-wp_genesis 82 function _lines($lines, $prefix = ' ', $encode = true)
mp-wp_genesis 83 {
mp-wp_genesis 84 if ($encode) {
mp-wp_genesis 85 array_walk($lines, array(&$this, '_encode'));
mp-wp_genesis 86 }
mp-wp_genesis 87
mp-wp_genesis 88 if ($this->_split_level == 'words') {
mp-wp_genesis 89 return implode('', $lines);
mp-wp_genesis 90 } else {
mp-wp_genesis 91 return implode("\n", $lines) . "\n";
mp-wp_genesis 92 }
mp-wp_genesis 93 }
mp-wp_genesis 94
mp-wp_genesis 95 function _added($lines)
mp-wp_genesis 96 {
mp-wp_genesis 97 array_walk($lines, array(&$this, '_encode'));
mp-wp_genesis 98 $lines[0] = $this->_ins_prefix . $lines[0];
mp-wp_genesis 99 $lines[count($lines) - 1] .= $this->_ins_suffix;
mp-wp_genesis 100 return $this->_lines($lines, ' ', false);
mp-wp_genesis 101 }
mp-wp_genesis 102
mp-wp_genesis 103 function _deleted($lines, $words = false)
mp-wp_genesis 104 {
mp-wp_genesis 105 array_walk($lines, array(&$this, '_encode'));
mp-wp_genesis 106 $lines[0] = $this->_del_prefix . $lines[0];
mp-wp_genesis 107 $lines[count($lines) - 1] .= $this->_del_suffix;
mp-wp_genesis 108 return $this->_lines($lines, ' ', false);
mp-wp_genesis 109 }
mp-wp_genesis 110
mp-wp_genesis 111 function _changed($orig, $final)
mp-wp_genesis 112 {
mp-wp_genesis 113 /* If we've already split on words, don't try to do so again - just
mp-wp_genesis 114 * display. */
mp-wp_genesis 115 if ($this->_split_level == 'words') {
mp-wp_genesis 116 $prefix = '';
mp-wp_genesis 117 while ($orig[0] !== false && $final[0] !== false &&
mp-wp_genesis 118 substr($orig[0], 0, 1) == ' ' &&
mp-wp_genesis 119 substr($final[0], 0, 1) == ' ') {
mp-wp_genesis 120 $prefix .= substr($orig[0], 0, 1);
mp-wp_genesis 121 $orig[0] = substr($orig[0], 1);
mp-wp_genesis 122 $final[0] = substr($final[0], 1);
mp-wp_genesis 123 }
mp-wp_genesis 124 return $prefix . $this->_deleted($orig) . $this->_added($final);
mp-wp_genesis 125 }
mp-wp_genesis 126
mp-wp_genesis 127 $text1 = implode("\n", $orig);
mp-wp_genesis 128 $text2 = implode("\n", $final);
mp-wp_genesis 129
mp-wp_genesis 130 /* Non-printing newline marker. */
mp-wp_genesis 131 $nl = "\0";
mp-wp_genesis 132
mp-wp_genesis 133 /* We want to split on word boundaries, but we need to
mp-wp_genesis 134 * preserve whitespace as well. Therefore we split on words,
mp-wp_genesis 135 * but include all blocks of whitespace in the wordlist. */
mp-wp_genesis 136 $diff = new Text_Diff($this->_splitOnWords($text1, $nl),
mp-wp_genesis 137 $this->_splitOnWords($text2, $nl));
mp-wp_genesis 138
mp-wp_genesis 139 /* Get the diff in inline format. */
mp-wp_genesis 140 $renderer = new Text_Diff_Renderer_inline(array_merge($this->getParams(),
mp-wp_genesis 141 array('split_level' => 'words')));
mp-wp_genesis 142
mp-wp_genesis 143 /* Run the diff and get the output. */
mp-wp_genesis 144 return str_replace($nl, "\n", $renderer->render($diff)) . "\n";
mp-wp_genesis 145 }
mp-wp_genesis 146
mp-wp_genesis 147 function _splitOnWords($string, $newlineEscape = "\n")
mp-wp_genesis 148 {
mp-wp_genesis 149 // Ignore \0; otherwise the while loop will never finish.
mp-wp_genesis 150 $string = str_replace("\0", '', $string);
mp-wp_genesis 151
mp-wp_genesis 152 $words = array();
mp-wp_genesis 153 $length = strlen($string);
mp-wp_genesis 154 $pos = 0;
mp-wp_genesis 155
mp-wp_genesis 156 while ($pos < $length) {
mp-wp_genesis 157 // Eat a word with any preceding whitespace.
mp-wp_genesis 158 $spaces = strspn(substr($string, $pos), " \n");
mp-wp_genesis 159 $nextpos = strcspn(substr($string, $pos + $spaces), " \n");
mp-wp_genesis 160 $words[] = str_replace("\n", $newlineEscape, substr($string, $pos, $spaces + $nextpos));
mp-wp_genesis 161 $pos += $spaces + $nextpos;
mp-wp_genesis 162 }
mp-wp_genesis 163
mp-wp_genesis 164 return $words;
mp-wp_genesis 165 }
mp-wp_genesis 166
mp-wp_genesis 167 function _encode(&$string)
mp-wp_genesis 168 {
mp-wp_genesis 169 $string = htmlspecialchars($string);
mp-wp_genesis 170 }
mp-wp_genesis 171
mp-wp_genesis 172 }