3 * Base for diff rendering classes. Portions taken from phpwiki-1.3.3.
5 * Copyright © 2000, 2001 Geoffrey T. Dairiki <dairiki@dairiki.org>
6 * You may copy this code freely under the conditions of the GPL.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 * http://www.gnu.org/copyleft/gpl.html
24 * @ingroup DifferenceEngine
28 * Base class for diff formatters
30 * This class formats the diff in classic diff format.
31 * It is intended that this class be customized via inheritance,
32 * to obtain fancier outputs.
34 * @ingroup DifferenceEngine
36 abstract class DiffFormatter
{
38 /** @var int Number of leading context "lines" to preserve.
40 * This should be left at zero for this class, but subclasses
41 * may want to set this to other values.
43 protected $leadingContextLines = 0;
45 /** @var int Number of trailing context "lines" to preserve.
47 * This should be left at zero for this class, but subclasses
48 * may want to set this to other values.
50 protected $trailingContextLines = 0;
52 /** @var string The output buffer; holds the output while it is built. */
60 * @return string The formatted output.
62 public function format( $diff ) {
67 $nlead = $this->leadingContextLines
;
68 $ntrail = $this->trailingContextLines
;
72 // Initialize $x0 and $y0 to prevent IDEs from getting confused.
74 foreach ( $diff->edits
as $edit ) {
75 if ( $edit->type
== 'copy' ) {
76 if ( is_array( $block ) ) {
77 if ( count( $edit->orig
) <= $nlead +
$ntrail ) {
81 $context = array_slice( $edit->orig
, 0, $ntrail );
82 $block[] = new DiffOpCopy( $context );
84 $this->block( $x0, $ntrail +
$xi - $x0,
85 $y0, $ntrail +
$yi - $y0,
90 $context = $edit->orig
;
92 if ( !is_array( $block ) ) {
93 $context = array_slice( $context, count( $context ) - $nlead );
94 $x0 = $xi - count( $context );
95 $y0 = $yi - count( $context );
98 $block[] = new DiffOpCopy( $context );
105 $xi +
= count( $edit->orig
);
107 if ( $edit->closing
) {
108 $yi +
= count( $edit->closing
);
112 if ( is_array( $block ) ) {
113 $this->block( $x0, $xi - $x0,
118 $end = $this->endDiff();
128 * @param array $edits
130 * @throws MWException If the edit type is not known.
132 protected function block( $xbeg, $xlen, $ybeg, $ylen, &$edits ) {
133 $this->startBlock( $this->blockHeader( $xbeg, $xlen, $ybeg, $ylen ) );
134 foreach ( $edits as $edit ) {
135 if ( $edit->type
== 'copy' ) {
136 $this->context( $edit->orig
);
137 } elseif ( $edit->type
== 'add' ) {
138 $this->added( $edit->closing
);
139 } elseif ( $edit->type
== 'delete' ) {
140 $this->deleted( $edit->orig
);
141 } elseif ( $edit->type
== 'change' ) {
142 $this->changed( $edit->orig
, $edit->closing
);
144 throw new MWException( "Unknown edit type: {$edit->type}" );
150 protected function startDiff() {
155 * Writes a string to the output buffer.
157 * @param string $text
159 protected function writeOutput( $text ) {
160 $this->result
.= $text;
166 protected function endDiff() {
167 $val = $this->result
;
181 protected function blockHeader( $xbeg, $xlen, $ybeg, $ylen ) {
183 $xbeg .= ',' . ( $xbeg +
$xlen - 1 );
186 $ybeg .= ',' . ( $ybeg +
$ylen - 1 );
189 return $xbeg . ( $xlen ?
( $ylen ?
'c' : 'd' ) : 'a' ) . $ybeg;
193 * Called at the start of a block of connected edits.
194 * This default implementation writes the header and a newline to the output buffer.
196 * @param string $header
198 protected function startBlock( $header ) {
199 $this->writeOutput( $header . "\n" );
203 * Called at the end of a block of connected edits.
204 * This default implementation does nothing.
206 protected function endBlock() {
210 * Writes all (optionally prefixed) lines to the output buffer, separated by newlines.
212 * @param string[] $lines
213 * @param string $prefix
215 protected function lines( $lines, $prefix = ' ' ) {
216 foreach ( $lines as $line ) {
217 $this->writeOutput( "$prefix $line\n" );
222 * @param string[] $lines
224 protected function context( $lines ) {
225 $this->lines( $lines );
229 * @param string[] $lines
231 protected function added( $lines ) {
232 $this->lines( $lines, '>' );
236 * @param string[] $lines
238 protected function deleted( $lines ) {
239 $this->lines( $lines, '<' );
243 * Writes the two sets of lines to the output buffer, separated by "---" and a newline.
245 * @param string[] $orig
246 * @param string[] $closing
248 protected function changed( $orig, $closing ) {
249 $this->deleted( $orig );
250 $this->writeOutput( "---\n" );
251 $this->added( $closing );