<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul, pre { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[13211] trunk/wp-includes/Text: Update Text_Diff.</title>
</head>
<body>

<div id="msg">
<dl>
<dt>Revision</dt> <dd><a href="http://trac.wordpress.org/changeset/13211">13211</a></dd>
<dt>Author</dt> <dd>nacin</dd>
<dt>Date</dt> <dd>2010-02-19 01:25:26 +0000 (Fri, 19 Feb 2010)</dd>
</dl>

<h3>Log Message</h3>
<pre>Update Text_Diff. Props simek. Fixes <a href="http://trac.wordpress.org/ticket/9467">#9467</a></pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkwpincludesTextDiffEnginenativephp">trunk/wp-includes/Text/Diff/Engine/native.php</a></li>
<li><a href="#trunkwpincludesTextDiffEngineshellphp">trunk/wp-includes/Text/Diff/Engine/shell.php</a></li>
<li><a href="#trunkwpincludesTextDiffEnginestringphp">trunk/wp-includes/Text/Diff/Engine/string.php</a></li>
<li><a href="#trunkwpincludesTextDiffEnginexdiffphp">trunk/wp-includes/Text/Diff/Engine/xdiff.php</a></li>
<li><a href="#trunkwpincludesTextDiffRendererinlinephp">trunk/wp-includes/Text/Diff/Renderer/inline.php</a></li>
<li><a href="#trunkwpincludesTextDiffRendererphp">trunk/wp-includes/Text/Diff/Renderer.php</a></li>
<li><a href="#trunkwpincludesTextDiffphp">trunk/wp-includes/Text/Diff.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkwpincludesTextDiffEnginenativephp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/Text/Diff/Engine/native.php (13210 => 13211)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/Text/Diff/Engine/native.php        2010-02-19 01:08:39 UTC (rev 13210)
+++ trunk/wp-includes/Text/Diff/Engine/native.php        2010-02-19 01:25:26 UTC (rev 13211)
</span><span class="lines">@@ -1,9 +1,8 @@
</span><span class="cx"> &lt;?php
</span><span class="cx"> /**
</span><del>- * $Horde: framework/Text_Diff/Diff/Engine/native.php,v 1.10 2008/01/04 10:27:53 jan Exp $
</del><ins>+ * Class used internally by Text_Diff to actually compute the diffs.
</ins><span class="cx">  *
</span><del>- * Class used internally by Text_Diff to actually compute the diffs. This
- * class is implemented using native PHP code.
</del><ins>+ * This class is implemented using native PHP code.
</ins><span class="cx">  *
</span><span class="cx">  * The algorithm used here is mostly lifted from the perl module
</span><span class="cx">  * Algorithm::Diff (version 1.06) by Ned Konz, which is available at:
</span><span class="lines">@@ -19,7 +18,7 @@
</span><span class="cx">  * Geoffrey T. Dairiki &lt;dairiki@dairiki.org&gt;. The original PHP version of this
</span><span class="cx">  * code was written by him, and is used/adapted with his permission.
</span><span class="cx">  *
</span><del>- * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
</del><ins>+ * Copyright 2004-2010 The Horde Project (http://www.horde.org/)
</ins><span class="cx">  *
</span><span class="cx">  * See the enclosed file COPYING for license information (LGPL). If you did
</span><span class="cx">  * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
</span></span></pre></div>
<a id="trunkwpincludesTextDiffEngineshellphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/Text/Diff/Engine/shell.php (13210 => 13211)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/Text/Diff/Engine/shell.php        2010-02-19 01:08:39 UTC (rev 13210)
+++ trunk/wp-includes/Text/Diff/Engine/shell.php        2010-02-19 01:25:26 UTC (rev 13211)
</span><span class="lines">@@ -5,10 +5,8 @@
</span><span class="cx">  * This class uses the Unix `diff` program via shell_exec to compute the
</span><span class="cx">  * differences between the two input arrays.
</span><span class="cx">  *
</span><del>- * $Horde: framework/Text_Diff/Diff/Engine/shell.php,v 1.8 2008/01/04 10:07:50 jan Exp $
</del><ins>+ * Copyright 2007-2010 The Horde Project (http://www.horde.org/)
</ins><span class="cx">  *
</span><del>- * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
- *
</del><span class="cx">  * See the enclosed file COPYING for license information (LGPL). If you did
</span><span class="cx">  * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
</span><span class="cx">  *
</span></span></pre></div>
<a id="trunkwpincludesTextDiffEnginestringphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/Text/Diff/Engine/string.php (13210 => 13211)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/Text/Diff/Engine/string.php        2010-02-19 01:08:39 UTC (rev 13210)
+++ trunk/wp-includes/Text/Diff/Engine/string.php        2010-02-19 01:25:26 UTC (rev 13211)
</span><span class="lines">@@ -10,10 +10,8 @@
</span><span class="cx">  * echo $renderer-&gt;render($diff);
</span><span class="cx">  * &lt;/code&gt;
</span><span class="cx">  *
</span><del>- * $Horde: framework/Text_Diff/Diff/Engine/string.php,v 1.7 2008/01/04 10:07:50 jan Exp $
- *
</del><span class="cx">  * Copyright 2005 \xD6rjan Persson &lt;o@42mm.org&gt;
</span><del>- * Copyright 2005-2008 The Horde Project (http://www.horde.org/)
</del><ins>+ * Copyright 2005-2010 The Horde Project (http://www.horde.org/)
</ins><span class="cx">  *
</span><span class="cx">  * See the enclosed file COPYING for license information (LGPL). If you did
</span><span class="cx">  * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
</span><span class="lines">@@ -39,6 +37,19 @@
</span><span class="cx">      */
</span><span class="cx">     function diff($diff, $mode = 'autodetect')
</span><span class="cx">     {
</span><ins>+        // Detect line breaks.
+        $lnbr = &quot;\n&quot;;
+        if (strpos($diff, &quot;\r\n&quot;) !== false) {
+            $lnbr = &quot;\r\n&quot;;
+        } elseif (strpos($diff, &quot;\r&quot;) !== false) {
+            $lnbr = &quot;\r&quot;;
+        }
+
+        // Make sure we have a line break at the EOF.
+        if (substr($diff, -strlen($lnbr)) != $lnbr) {
+            $diff .= $lnbr;
+        }
+
</ins><span class="cx">         if ($mode != 'autodetect' &amp;&amp; $mode != 'context' &amp;&amp; $mode != 'unified') {
</span><span class="cx">             return PEAR::raiseError('Type of diff is unsupported');
</span><span class="cx">         }
</span><span class="lines">@@ -48,17 +59,20 @@
</span><span class="cx">             $unified = strpos($diff, '---');
</span><span class="cx">             if ($context === $unified) {
</span><span class="cx">                 return PEAR::raiseError('Type of diff could not be detected');
</span><del>-            } elseif ($context === false || $context === false) {
</del><ins>+            } elseif ($context === false || $unified === false) {
</ins><span class="cx">                 $mode = $context !== false ? 'context' : 'unified';
</span><span class="cx">             } else {
</span><span class="cx">                 $mode = $context &lt; $unified ? 'context' : 'unified';
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        // split by new line and remove the diff header
-        $diff = explode(&quot;\n&quot;, $diff);
-        array_shift($diff);
-        array_shift($diff);
</del><ins>+        // Split by new line and remove the diff header, if there is one.
+        $diff = explode($lnbr, $diff);
+        if (($mode == 'context' &amp;&amp; strpos($diff[0], '***') === 0) ||
+            ($mode == 'unified' &amp;&amp; strpos($diff[0], '---') === 0)) {
+            array_shift($diff);
+            array_shift($diff);
+        }
</ins><span class="cx"> 
</span><span class="cx">         if ($mode == 'context') {
</span><span class="cx">             return $this-&gt;parseContextDiff($diff);
</span></span></pre></div>
<a id="trunkwpincludesTextDiffEnginexdiffphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/Text/Diff/Engine/xdiff.php (13210 => 13211)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/Text/Diff/Engine/xdiff.php        2010-02-19 01:08:39 UTC (rev 13210)
+++ trunk/wp-includes/Text/Diff/Engine/xdiff.php        2010-02-19 01:25:26 UTC (rev 13211)
</span><span class="lines">@@ -5,10 +5,8 @@
</span><span class="cx">  * This class uses the xdiff PECL package (http://pecl.php.net/package/xdiff)
</span><span class="cx">  * to compute the differences between the two input arrays.
</span><span class="cx">  *
</span><del>- * $Horde: framework/Text_Diff/Diff/Engine/xdiff.php,v 1.6 2008/01/04 10:07:50 jan Exp $
</del><ins>+ * Copyright 2004-2010 The Horde Project (http://www.horde.org/)
</ins><span class="cx">  *
</span><del>- * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
- *
</del><span class="cx">  * See the enclosed file COPYING for license information (LGPL). If you did
</span><span class="cx">  * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
</span><span class="cx">  *
</span><span class="lines">@@ -42,6 +40,9 @@
</span><span class="cx">          * valid, albeit a little less descriptive and efficient. */
</span><span class="cx">         $edits = array();
</span><span class="cx">         foreach ($diff as $line) {
</span><ins>+            if (!strlen($line)) {
+                continue;
+            }
</ins><span class="cx">             switch ($line[0]) {
</span><span class="cx">             case ' ':
</span><span class="cx">                 $edits[] = &amp;new Text_Diff_Op_copy(array(substr($line, 1)));
</span></span></pre></div>
<a id="trunkwpincludesTextDiffRendererinlinephp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/Text/Diff/Renderer/inline.php (13210 => 13211)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/Text/Diff/Renderer/inline.php        2010-02-19 01:08:39 UTC (rev 13210)
+++ trunk/wp-includes/Text/Diff/Renderer/inline.php        2010-02-19 01:25:26 UTC (rev 13211)
</span><span class="lines">@@ -2,10 +2,8 @@
</span><span class="cx"> /**
</span><span class="cx">  * &quot;Inline&quot; diff renderer.
</span><span class="cx">  *
</span><del>- * $Horde: framework/Text_Diff/Diff/Renderer/inline.php,v 1.21 2008/01/04 10:07:51 jan Exp $
</del><ins>+ * Copyright 2004-2010 The Horde Project (http://www.horde.org/)
</ins><span class="cx">  *
</span><del>- * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
- *
</del><span class="cx">  * See the enclosed file COPYING for license information (LGPL). If you did
</span><span class="cx">  * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
</span><span class="cx">  *
</span><span class="lines">@@ -30,42 +28,65 @@
</span><span class="cx"> 
</span><span class="cx">     /**
</span><span class="cx">      * Number of leading context &quot;lines&quot; to preserve.
</span><ins>+     *
+     * @var integer
</ins><span class="cx">      */
</span><span class="cx">     var $_leading_context_lines = 10000;
</span><span class="cx"> 
</span><span class="cx">     /**
</span><span class="cx">      * Number of trailing context &quot;lines&quot; to preserve.
</span><ins>+     *
+     * @var integer
</ins><span class="cx">      */
</span><span class="cx">     var $_trailing_context_lines = 10000;
</span><span class="cx"> 
</span><span class="cx">     /**
</span><span class="cx">      * Prefix for inserted text.
</span><ins>+     *
+     * @var string
</ins><span class="cx">      */
</span><span class="cx">     var $_ins_prefix = '&lt;ins&gt;';
</span><span class="cx"> 
</span><span class="cx">     /**
</span><span class="cx">      * Suffix for inserted text.
</span><ins>+     *
+     * @var string
</ins><span class="cx">      */
</span><span class="cx">     var $_ins_suffix = '&lt;/ins&gt;';
</span><span class="cx"> 
</span><span class="cx">     /**
</span><span class="cx">      * Prefix for deleted text.
</span><ins>+     *
+     * @var string
</ins><span class="cx">      */
</span><span class="cx">     var $_del_prefix = '&lt;del&gt;';
</span><span class="cx"> 
</span><span class="cx">     /**
</span><span class="cx">      * Suffix for deleted text.
</span><ins>+     *
+     * @var string
</ins><span class="cx">      */
</span><span class="cx">     var $_del_suffix = '&lt;/del&gt;';
</span><span class="cx"> 
</span><span class="cx">     /**
</span><span class="cx">      * Header for each change block.
</span><ins>+     *
+     * @var string
</ins><span class="cx">      */
</span><span class="cx">     var $_block_header = '';
</span><span class="cx"> 
</span><span class="cx">     /**
</span><ins>+     * Whether to split down to character-level.
+     *
+     * @var boolean
+     */
+    var $_split_characters = false;
+
+    /**
</ins><span class="cx">      * What are we currently splitting on? Used to recurse to show word-level
</span><del>-     * changes.
</del><ins>+     * or character-level changes.
+     *
+     * @var string
</ins><span class="cx">      */
</span><span class="cx">     var $_split_level = 'lines';
</span><span class="cx"> 
</span><span class="lines">@@ -85,10 +106,10 @@
</span><span class="cx">             array_walk($lines, array(&amp;$this, '_encode'));
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if ($this-&gt;_split_level == 'words') {
</del><ins>+        if ($this-&gt;_split_level == 'lines') {
+            return implode(&quot;\n&quot;, $lines) . &quot;\n&quot;;
+        } else {
</ins><span class="cx">             return implode('', $lines);
</span><del>-        } else {
-            return implode(&quot;\n&quot;, $lines) . &quot;\n&quot;;
</del><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -110,8 +131,13 @@
</span><span class="cx"> 
</span><span class="cx">     function _changed($orig, $final)
</span><span class="cx">     {
</span><del>-        /* If we've already split on words, don't try to do so again - just
-         * display. */
</del><ins>+        /* If we've already split on characters, just display. */
+        if ($this-&gt;_split_level == 'characters') {
+            return $this-&gt;_deleted($orig)
+                . $this-&gt;_added($final);
+        }
+
+        /* If we've already split on words, just display. */
</ins><span class="cx">         if ($this-&gt;_split_level == 'words') {
</span><span class="cx">             $prefix = '';
</span><span class="cx">             while ($orig[0] !== false &amp;&amp; $final[0] !== false &amp;&amp;
</span><span class="lines">@@ -130,15 +156,23 @@
</span><span class="cx">         /* Non-printing newline marker. */
</span><span class="cx">         $nl = &quot;\0&quot;;
</span><span class="cx"> 
</span><del>-        /* We want to split on word boundaries, but we need to
-         * preserve whitespace as well. Therefore we split on words,
-         * but include all blocks of whitespace in the wordlist. */
-        $diff = new Text_Diff($this-&gt;_splitOnWords($text1, $nl),
-                              $this-&gt;_splitOnWords($text2, $nl));
</del><ins>+        if ($this-&gt;_split_characters) {
+            $diff = new Text_Diff('native',
+                                  array(preg_split('//', $text1),
+                                        preg_split('//', $text2)));
+        } else {
+            /* We want to split on word boundaries, but we need to preserve
+             * whitespace as well. Therefore we split on words, but include
+             * all blocks of whitespace in the wordlist. */
+            $diff = new Text_Diff('native',
+                                  array($this-&gt;_splitOnWords($text1, $nl),
+                                        $this-&gt;_splitOnWords($text2, $nl)));
+        }
</ins><span class="cx"> 
</span><span class="cx">         /* Get the diff in inline format. */
</span><del>-        $renderer = new Text_Diff_Renderer_inline(array_merge($this-&gt;getParams(),
-                                                              array('split_level' =&gt; 'words')));
</del><ins>+        $renderer = new Text_Diff_Renderer_inline
+            (array_merge($this-&gt;getParams(),
+                         array('split_level' =&gt; $this-&gt;_split_characters ? 'characters' : 'words')));
</ins><span class="cx"> 
</span><span class="cx">         /* Run the diff and get the output. */
</span><span class="cx">         return str_replace($nl, &quot;\n&quot;, $renderer-&gt;render($diff)) . &quot;\n&quot;;
</span></span></pre></div>
<a id="trunkwpincludesTextDiffRendererphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/Text/Diff/Renderer.php (13210 => 13211)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/Text/Diff/Renderer.php        2010-02-19 01:08:39 UTC (rev 13210)
+++ trunk/wp-includes/Text/Diff/Renderer.php        2010-02-19 01:25:26 UTC (rev 13211)
</span><span class="lines">@@ -5,10 +5,8 @@
</span><span class="cx">  * This class renders the diff in classic diff format. It is intended that
</span><span class="cx">  * this class be customized via inheritance, to obtain fancier outputs.
</span><span class="cx">  *
</span><del>- * $Horde: framework/Text_Diff/Diff/Renderer.php,v 1.21 2008/01/04 10:07:50 jan Exp $
</del><ins>+ * Copyright 2004-2010 The Horde Project (http://www.horde.org/)
</ins><span class="cx">  *
</span><del>- * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
- *
</del><span class="cx">  * See the enclosed file COPYING for license information (LGPL). If you did
</span><span class="cx">  * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
</span><span class="cx">  *
</span></span></pre></div>
<a id="trunkwpincludesTextDiffphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/Text/Diff.php (13210 => 13211)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/Text/Diff.php        2010-02-19 01:08:39 UTC (rev 13210)
+++ trunk/wp-includes/Text/Diff.php        2010-02-19 01:25:26 UTC (rev 13211)
</span><span class="lines">@@ -6,10 +6,8 @@
</span><span class="cx">  * The original PHP version of this code was written by Geoffrey T. Dairiki
</span><span class="cx">  * &lt;dairiki@dairiki.org&gt;, and is used/adapted with his permission.
</span><span class="cx">  *
</span><del>- * $Horde: framework/Text_Diff/Diff.php,v 1.26 2008/01/04 10:07:49 jan Exp $
- *
</del><span class="cx">  * Copyright 2004 Geoffrey T. Dairiki &lt;dairiki@dairiki.org&gt;
</span><del>- * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
</del><ins>+ * Copyright 2004-2010 The Horde Project (http://www.horde.org/)
</ins><span class="cx">  *
</span><span class="cx">  * See the enclosed file COPYING for license information (LGPL). If you did
</span><span class="cx">  * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
</span><span class="lines">@@ -66,6 +64,44 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     /**
</span><ins>+     * returns the number of new (added) lines in a given diff.
+     *
+     * @since Text_Diff 1.1.0
+     *
+     * @return integer The number of new lines
+     */
+    function countAddedLines()
+    {
+        $count = 0;
+        foreach ($this-&gt;_edits as $edit) {
+            if (is_a($edit, 'Text_Diff_Op_add') ||
+                is_a($edit, 'Text_Diff_Op_change')) {
+                $count += $edit-&gt;nfinal();
+            }
+        }
+        return $count;
+    }
+
+    /**
+     * Returns the number of deleted (removed) lines in a given diff.
+     *
+     * @since Text_Diff 1.1.0
+     *
+     * @return integer The number of deleted lines
+     */
+    function countDeletedLines()
+    {
+        $count = 0;
+        foreach ($this-&gt;_edits as $edit) {
+            if (is_a($edit, 'Text_Diff_Op_delete') ||
+                is_a($edit, 'Text_Diff_Op_change')) {
+                $count += $edit-&gt;norig();
+            }
+        }
+        return $count;
+    }
+
+    /**
</ins><span class="cx">      * Computes a reversed diff.
</span><span class="cx">      *
</span><span class="cx">      * Example:
</span></span></pre>
</div>
</div>

</body>
</html>