position = [ 'right-pos' => $rightPos + 1, 'left-pos' => $leftPos + 1, ]; } /** * @param string $line Line in the right text but not in the left */ public function add( $line ) { $this->new[] = $line; } /** * @param string $line Line in the left text but not in the right */ public function subtract( $line ) { $this->old[] = $line; } /** * @return array[] set of changes * Each change consists of: * An 'action', one of: * - add * - subtract * - change * 'content' that was added or removed, or in the case * of a change, 'old_content' and 'new_content' * 'left_pos' and 'right_pos' (in 1-indexed lines) of the change. */ public function getChangeSet() { $old = implode( "\n", $this->old ); $new = implode( "\n", $this->new ); $position = $this->position; $changeSet = []; // The implodes must come first because we consider [ '' ] to also be false // meaning a blank link replaced with content is an addition if ( $old && $new ) { $min = min( count( $this->old ), count( $this->new ) ); $changeSet[] = $position + [ 'action' => 'change', 'old_content' => implode( "\n", array_slice( $this->old, 0, $min ) ), 'new_content' => implode( "\n", array_slice( $this->new, 0, $min ) ), ]; $position['left-pos'] += $min; $position['right-pos'] += $min; $old = implode( "\n", array_slice( $this->old, $min ) ); $new = implode( "\n", array_slice( $this->new, $min ) ); } if ( $new ) { $changeSet[] = $position + [ 'action' => 'add', 'content' => $new, ]; } elseif ( $old ) { $changeSet[] = $position + [ 'action' => 'subtract', 'content' => $old, ]; } return $changeSet; } }