WordPress.org

Make WordPress Core

Ticket #9467: textdiff.new.version.patch

File textdiff.new.version.patch, 18.8 KB (added by Simek, 8 years ago)

Most recent version according to http://cvs.horde.org/framework/Text_Diff/

  • Diff.php

     
    66 * The original PHP version of this code was written by Geoffrey T. Dairiki
    77 * <dairiki@dairiki.org>, and is used/adapted with his permission.
    88 *
    9  * $Horde: framework/Text_Diff/Diff.php,v 1.26 2008/01/04 10:07:49 jan Exp $
    10  *
    119 * Copyright 2004 Geoffrey T. Dairiki <dairiki@dairiki.org>
    12  * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
     10 * Copyright 2004-2010 The Horde Project (http://www.horde.org/)
    1311 *
    1412 * See the enclosed file COPYING for license information (LGPL). If you did
    1513 * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
     
    4947            $engine = basename($engine);
    5048        }
    5149
    52         // WP #7391
     50        // WP path fix
    5351        require_once dirname(__FILE__).'/Diff/Engine/' . $engine . '.php';
    5452        $class = 'Text_Diff_Engine_' . $engine;
    5553        $diff_engine = new $class();
     
    6664    }
    6765
    6866    /**
     67     * returns the number of new (added) lines in a given diff.
     68     *
     69     * @since Text_Diff 1.1.0
     70     *
     71     * @return integer The number of new lines
     72     */
     73    function countAddedLines()
     74    {
     75        $count = 0;
     76        foreach ($this->_edits as $edit) {
     77            if (is_a($edit, 'Text_Diff_Op_add') ||
     78                is_a($edit, 'Text_Diff_Op_change')) {
     79                $count += $edit->nfinal();
     80            }
     81        }
     82        return $count;
     83    }
     84
     85    /**
     86     * Returns the number of deleted (removed) lines in a given diff.
     87     *
     88     * @since Text_Diff 1.1.0
     89     *
     90     * @return integer The number of deleted lines
     91     */
     92    function countDeletedLines()
     93    {
     94        $count = 0;
     95        foreach ($this->_edits as $edit) {
     96            if (is_a($edit, 'Text_Diff_Op_delete') ||
     97                is_a($edit, 'Text_Diff_Op_change')) {
     98                $count += $edit->norig();
     99            }
     100        }
     101        return $count;
     102    }
     103
     104    /**
    69105     * Computes a reversed diff.
    70106     *
    71107     * Example:
     
    341377
    342378    function &reverse()
    343379    {
    344         $reverse = &new Text_Diff_Op_copy($this->final, $this->orig);
     380        $reverse = new Text_Diff_Op_copy($this->final, $this->orig);
    345381        return $reverse;
    346382    }
    347383
     
    363399
    364400    function &reverse()
    365401    {
    366         $reverse = &new Text_Diff_Op_add($this->orig);
     402        $reverse = new Text_Diff_Op_add($this->orig);
    367403        return $reverse;
    368404    }
    369405
     
    385421
    386422    function &reverse()
    387423    {
    388         $reverse = &new Text_Diff_Op_delete($this->final);
     424        $reverse = new Text_Diff_Op_delete($this->final);
    389425        return $reverse;
    390426    }
    391427
     
    407443
    408444    function &reverse()
    409445    {
    410         $reverse = &new Text_Diff_Op_change($this->final, $this->orig);
     446        $reverse = new Text_Diff_Op_change($this->final, $this->orig);
    411447        return $reverse;
    412448    }
    413449
  • Diff/Engine/native.php

     
    11<?php
    22/**
    3  * $Horde: framework/Text_Diff/Diff/Engine/native.php,v 1.10 2008/01/04 10:27:53 jan Exp $
     3 * Class used internally by Text_Diff to actually compute the diffs.
    44 *
    5  * Class used internally by Text_Diff to actually compute the diffs. This
    6  * class is implemented using native PHP code.
     5 * This class is implemented using native PHP code.
    76 *
    87 * The algorithm used here is mostly lifted from the perl module
    98 * Algorithm::Diff (version 1.06) by Ned Konz, which is available at:
     
    1918 * Geoffrey T. Dairiki <dairiki@dairiki.org>. The original PHP version of this
    2019 * code was written by him, and is used/adapted with his permission.
    2120 *
    22  * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
     21 * Copyright 2004-2010 The Horde Project (http://www.horde.org/)
    2322 *
    2423 * See the enclosed file COPYING for license information (LGPL). If you did
    2524 * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
     
    105104                ++$yi;
    106105            }
    107106            if ($copy) {
    108                 $edits[] = &new Text_Diff_Op_copy($copy);
     107                $edits[] = new Text_Diff_Op_copy($copy);
    109108            }
    110109
    111110            // Find deletes & adds.
     
    120119            }
    121120
    122121            if ($delete && $add) {
    123                 $edits[] = &new Text_Diff_Op_change($delete, $add);
     122                $edits[] = new Text_Diff_Op_change($delete, $add);
    124123            } elseif ($delete) {
    125                 $edits[] = &new Text_Diff_Op_delete($delete);
     124                $edits[] = new Text_Diff_Op_delete($delete);
    126125            } elseif ($add) {
    127                 $edits[] = &new Text_Diff_Op_add($add);
     126                $edits[] = new Text_Diff_Op_add($add);
    128127            }
    129128        }
    130129
  • Diff/Engine/shell.php

     
    55 * This class uses the Unix `diff` program via shell_exec to compute the
    66 * differences between the two input arrays.
    77 *
    8  * $Horde: framework/Text_Diff/Diff/Engine/shell.php,v 1.8 2008/01/04 10:07:50 jan Exp $
     8 * Copyright 2007-2010 The Horde Project (http://www.horde.org/)
    99 *
    10  * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
    11  *
    1210 * See the enclosed file COPYING for license information (LGPL). If you did
    1311 * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
    1412 *
  • Diff/Engine/string.php

     
    1010 * echo $renderer->render($diff);
    1111 * </code>
    1212 *
    13  * $Horde: framework/Text_Diff/Diff/Engine/string.php,v 1.7 2008/01/04 10:07:50 jan Exp $
    14  *
    1513 * Copyright 2005 Örjan Persson <o@42mm.org>
    16  * Copyright 2005-2008 The Horde Project (http://www.horde.org/)
     14 * Copyright 2005-2010 The Horde Project (http://www.horde.org/)
    1715 *
    1816 * See the enclosed file COPYING for license information (LGPL). If you did
    1917 * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
     
    3937     */
    4038    function diff($diff, $mode = 'autodetect')
    4139    {
     40        // Detect line breaks.
     41        $lnbr = "\n";
     42        if (strpos($diff, "\r\n") !== false) {
     43            $lnbr = "\r\n";
     44        } elseif (strpos($diff, "\r") !== false) {
     45            $lnbr = "\r";
     46        }
     47
     48        // Make sure we have a line break at the EOF.
     49        if (substr($diff, -strlen($lnbr)) != $lnbr) {
     50            $diff .= $lnbr;
     51        }
     52
    4253        if ($mode != 'autodetect' && $mode != 'context' && $mode != 'unified') {
    4354            return PEAR::raiseError('Type of diff is unsupported');
    4455        }
     
    4859            $unified = strpos($diff, '---');
    4960            if ($context === $unified) {
    5061                return PEAR::raiseError('Type of diff could not be detected');
    51             } elseif ($context === false || $context === false) {
     62            } elseif ($context === false || $unified === false) {
    5263                $mode = $context !== false ? 'context' : 'unified';
    5364            } else {
    5465                $mode = $context < $unified ? 'context' : 'unified';
    5566            }
    5667        }
    5768
    58         // split by new line and remove the diff header
    59         $diff = explode("\n", $diff);
    60         array_shift($diff);
    61         array_shift($diff);
     69        // Split by new line and remove the diff header, if there is one.
     70        $diff = explode($lnbr, $diff);
     71        if (($mode == 'context' && strpos($diff[0], '***') === 0) ||
     72            ($mode == 'unified' && strpos($diff[0], '---') === 0)) {
     73            array_shift($diff);
     74            array_shift($diff);
     75        }
    6276
    6377        if ($mode == 'context') {
    6478            return $this->parseContextDiff($diff);
     
    8599                do {
    86100                    $diff1[] = substr($diff[$i], 1);
    87101                } while (++$i < $end && substr($diff[$i], 0, 1) == ' ');
    88                 $edits[] = &new Text_Diff_Op_copy($diff1);
     102                $edits[] = new Text_Diff_Op_copy($diff1);
    89103                break;
    90104
    91105            case '+':
     
    93107                do {
    94108                    $diff1[] = substr($diff[$i], 1);
    95109                } while (++$i < $end && substr($diff[$i], 0, 1) == '+');
    96                 $edits[] = &new Text_Diff_Op_add($diff1);
     110                $edits[] = new Text_Diff_Op_add($diff1);
    97111                break;
    98112
    99113            case '-':
     
    107121                    $diff2[] = substr($diff[$i++], 1);
    108122                }
    109123                if (count($diff2) == 0) {
    110                     $edits[] = &new Text_Diff_Op_delete($diff1);
     124                    $edits[] = new Text_Diff_Op_delete($diff1);
    111125                } else {
    112                     $edits[] = &new Text_Diff_Op_change($diff1, $diff2);
     126                    $edits[] = new Text_Diff_Op_change($diff1, $diff2);
    113127                }
    114128                break;
    115129
     
    175189                $array[] = substr($diff[$j++], 2);
    176190            }
    177191            if (count($array) > 0) {
    178                 $edits[] = &new Text_Diff_Op_copy($array);
     192                $edits[] = new Text_Diff_Op_copy($array);
    179193            }
    180194
    181195            if ($i < $max_i) {
     
    189203                            $diff2[] = substr($diff[$j++], 2);
    190204                        }
    191205                    } while (++$i < $max_i && substr($diff[$i], 0, 1) == '!');
    192                     $edits[] = &new Text_Diff_Op_change($diff1, $diff2);
     206                    $edits[] = new Text_Diff_Op_change($diff1, $diff2);
    193207                    break;
    194208
    195209                case '+':
    196210                    do {
    197211                        $diff1[] = substr($diff[$i], 2);
    198212                    } while (++$i < $max_i && substr($diff[$i], 0, 1) == '+');
    199                     $edits[] = &new Text_Diff_Op_add($diff1);
     213                    $edits[] = new Text_Diff_Op_add($diff1);
    200214                    break;
    201215
    202216                case '-':
    203217                    do {
    204218                        $diff1[] = substr($diff[$i], 2);
    205219                    } while (++$i < $max_i && substr($diff[$i], 0, 1) == '-');
    206                     $edits[] = &new Text_Diff_Op_delete($diff1);
     220                    $edits[] = new Text_Diff_Op_delete($diff1);
    207221                    break;
    208222                }
    209223            }
     
    215229                    do {
    216230                        $diff2[] = substr($diff[$j++], 2);
    217231                    } while ($j < $max_j && substr($diff[$j], 0, 1) == '+');
    218                     $edits[] = &new Text_Diff_Op_add($diff2);
     232                    $edits[] = new Text_Diff_Op_add($diff2);
    219233                    break;
    220234
    221235                case '-':
    222236                    do {
    223237                        $diff2[] = substr($diff[$j++], 2);
    224238                    } while ($j < $max_j && substr($diff[$j], 0, 1) == '-');
    225                     $edits[] = &new Text_Diff_Op_delete($diff2);
     239                    $edits[] = new Text_Diff_Op_delete($diff2);
    226240                    break;
    227241                }
    228242            }
  • Diff/Engine/xdiff.php

     
    55 * This class uses the xdiff PECL package (http://pecl.php.net/package/xdiff)
    66 * to compute the differences between the two input arrays.
    77 *
    8  * $Horde: framework/Text_Diff/Diff/Engine/xdiff.php,v 1.6 2008/01/04 10:07:50 jan Exp $
     8 * Copyright 2004-2010 The Horde Project (http://www.horde.org/)
    99 *
    10  * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
    11  *
    1210 * See the enclosed file COPYING for license information (LGPL). If you did
    1311 * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
    1412 *
     
    4240         * valid, albeit a little less descriptive and efficient. */
    4341        $edits = array();
    4442        foreach ($diff as $line) {
     43            if (!strlen($line)) {
     44                continue;
     45            }
    4546            switch ($line[0]) {
    4647            case ' ':
    47                 $edits[] = &new Text_Diff_Op_copy(array(substr($line, 1)));
     48                $edits[] = new Text_Diff_Op_copy(array(substr($line, 1)));
    4849                break;
    4950
    5051            case '+':
    51                 $edits[] = &new Text_Diff_Op_add(array(substr($line, 1)));
     52                $edits[] = new Text_Diff_Op_add(array(substr($line, 1)));
    5253                break;
    5354
    5455            case '-':
    55                 $edits[] = &new Text_Diff_Op_delete(array(substr($line, 1)));
     56                $edits[] = new Text_Diff_Op_delete(array(substr($line, 1)));
    5657                break;
    5758            }
    5859        }
  • Diff/Renderer.php

     
    55 * This class renders the diff in classic diff format. It is intended that
    66 * this class be customized via inheritance, to obtain fancier outputs.
    77 *
    8  * $Horde: framework/Text_Diff/Diff/Renderer.php,v 1.21 2008/01/04 10:07:50 jan Exp $
     8 * Copyright 2004-2010 The Horde Project (http://www.horde.org/)
    99 *
    10  * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
    11  *
    1210 * See the enclosed file COPYING for license information (LGPL). If you did
    1311 * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
    1412 *
     
    10098                            /* Create a new block with as many lines as we need
    10199                             * for the trailing context. */
    102100                            $context = array_slice($edit->orig, 0, $ntrail);
    103                             $block[] = &new Text_Diff_Op_copy($context);
     101                            $block[] = new Text_Diff_Op_copy($context);
    104102                        }
    105103                        /* @todo */
    106104                        $output .= $this->_block($x0, $ntrail + $xi - $x0,
     
    120118                    $y0 = $yi - count($context);
    121119                    $block = array();
    122120                    if ($context) {
    123                         $block[] = &new Text_Diff_Op_copy($context);
     121                        $block[] = new Text_Diff_Op_copy($context);
    124122                    }
    125123                }
    126124                $block[] = $edit;
  • Diff/Renderer/inline.php

     
    22/**
    33 * "Inline" diff renderer.
    44 *
    5  * $Horde: framework/Text_Diff/Diff/Renderer/inline.php,v 1.21 2008/01/04 10:07:51 jan Exp $
     5 * Copyright 2004-2010 The Horde Project (http://www.horde.org/)
    66 *
    7  * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
    8  *
    97 * See the enclosed file COPYING for license information (LGPL). If you did
    108 * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
    119 *
     
    1513
    1614/** Text_Diff_Renderer */
    1715
    18 // WP #7391
     16// WP path fix
    1917require_once dirname(dirname(__FILE__)) . '/Renderer.php';
    2018
    2119/**
     
    3028
    3129    /**
    3230     * Number of leading context "lines" to preserve.
     31     *
     32     * @var integer
    3333     */
    3434    var $_leading_context_lines = 10000;
    3535
    3636    /**
    3737     * Number of trailing context "lines" to preserve.
     38     *
     39     * @var integer
    3840     */
    3941    var $_trailing_context_lines = 10000;
    4042
    4143    /**
    4244     * Prefix for inserted text.
     45     *
     46     * @var string
    4347     */
    4448    var $_ins_prefix = '<ins>';
    4549
    4650    /**
    4751     * Suffix for inserted text.
     52     *
     53     * @var string
    4854     */
    4955    var $_ins_suffix = '</ins>';
    5056
    5157    /**
    5258     * Prefix for deleted text.
     59     *
     60     * @var string
    5361     */
    5462    var $_del_prefix = '<del>';
    5563
    5664    /**
    5765     * Suffix for deleted text.
     66     *
     67     * @var string
    5868     */
    5969    var $_del_suffix = '</del>';
    6070
    6171    /**
    6272     * Header for each change block.
     73     *
     74     * @var string
    6375     */
    6476    var $_block_header = '';
    6577
    6678    /**
     79     * Whether to split down to character-level.
     80     *
     81     * @var boolean
     82     */
     83    var $_split_characters = false;
     84
     85    /**
    6786     * What are we currently splitting on? Used to recurse to show word-level
    68      * changes.
     87     * or character-level changes.
     88     *
     89     * @var string
    6990     */
    7091    var $_split_level = 'lines';
    7192
     
    85106            array_walk($lines, array(&$this, '_encode'));
    86107        }
    87108
    88         if ($this->_split_level == 'words') {
     109        if ($this->_split_level == 'lines') {
     110            return implode("\n", $lines) . "\n";
     111        } else {
    89112            return implode('', $lines);
    90         } else {
    91             return implode("\n", $lines) . "\n";
    92113        }
    93114    }
    94115
     
    110131
    111132    function _changed($orig, $final)
    112133    {
    113         /* If we've already split on words, don't try to do so again - just
    114          * display. */
     134        /* If we've already split on characters, just display. */
     135        if ($this->_split_level == 'characters') {
     136            return $this->_deleted($orig)
     137                . $this->_added($final);
     138        }
     139
     140        /* If we've already split on words, just display. */
    115141        if ($this->_split_level == 'words') {
    116142            $prefix = '';
    117143            while ($orig[0] !== false && $final[0] !== false &&
     
    130156        /* Non-printing newline marker. */
    131157        $nl = "\0";
    132158
    133         /* We want to split on word boundaries, but we need to
    134          * preserve whitespace as well. Therefore we split on words,
    135          * but include all blocks of whitespace in the wordlist. */
    136         $diff = new Text_Diff($this->_splitOnWords($text1, $nl),
    137                               $this->_splitOnWords($text2, $nl));
     159        if ($this->_split_characters) {
     160            $diff = new Text_Diff('native',
     161                                  array(preg_split('//', $text1),
     162                                        preg_split('//', $text2)));
     163        } else {
     164            /* We want to split on word boundaries, but we need to preserve
     165             * whitespace as well. Therefore we split on words, but include
     166             * all blocks of whitespace in the wordlist. */
     167            $diff = new Text_Diff('native',
     168                                  array($this->_splitOnWords($text1, $nl),
     169                                        $this->_splitOnWords($text2, $nl)));
     170        }
    138171
    139172        /* Get the diff in inline format. */
    140         $renderer = new Text_Diff_Renderer_inline(array_merge($this->getParams(),
    141                                                               array('split_level' => 'words')));
     173        $renderer = new Text_Diff_Renderer_inline
     174            (array_merge($this->getParams(),
     175                         array('split_level' => $this->_split_characters ? 'characters' : 'words')));
    142176
    143177        /* Run the diff and get the output. */
    144178        return str_replace($nl, "\n", $renderer->render($diff)) . "\n";