API:
authorRoan Kattouw <catrope@users.mediawiki.org>
Tue, 27 Nov 2007 21:36:43 +0000 (21:36 +0000)
committerRoan Kattouw <catrope@users.mediawiki.org>
Tue, 27 Nov 2007 21:36:43 +0000 (21:36 +0000)
* Adding rvdiffformat parameter to prop=revisions
* Creating formatters for unified (UnifiedDiffFormatter) and array (ArrayDiffFormatter) diffs

RELEASE-NOTES
includes/AutoLoader.php
includes/DifferenceEngine.php
includes/api/ApiQueryRevisions.php

index b6baf15..e3a8ae0 100644 (file)
@@ -300,6 +300,7 @@ Full API documentation is available at http://www.mediawiki.org/wiki/API
   name
 * (bug 11206) api.php should honor maxlag
 * Added diff generation to prop=revisions
+* Added support for traditional, unified and array diffs to prop=revisions
 
 === Languages updated in 1.12 ===
 
index 966f9af..afed43d 100644 (file)
@@ -57,6 +57,8 @@ function __autoload($className) {
                'Diff' => 'includes/DifferenceEngine.php',
                'MappedDiff' => 'includes/DifferenceEngine.php',
                'DiffFormatter' => 'includes/DifferenceEngine.php',
+               'UnifiedDiffFormatter' => 'includes/DifferenceEngine.php',
+               'ArrayDiffFormatter' => 'includes/DifferenceEngine.php',
                'DjVuImage' => 'includes/DjVuImage.php',
                '_HWLDF_WordAccumulator' => 'includes/DifferenceEngine.php',
                'WordLevelDiff' => 'includes/DifferenceEngine.php',
index 348fe0a..2730c98 100644 (file)
@@ -1677,6 +1677,84 @@ class DiffFormatter
        }
 }
 
+/**
+ * A formatter that outputs unified diffs
+ * @addtogroup DifferenceEngine
+ */
+
+class UnifiedDiffFormatter extends DiffFormatter
+{
+       var $leading_context_lines = 2;
+       var $trailing_context_lines = 2;
+       
+       function _added($lines) {
+               $this->_lines($lines, '+');
+       }
+       function _deleted($lines) {
+               $this->_lines($lines, '-');
+       }
+       function _changed($orig, $closing) {
+               $this->_deleted($orig);
+               $this->_added($closing);
+       }
+       function _block_header($xbeg, $xlen, $ybeg, $ylen) {
+               return "@@ -$xbeg,$xlen +$ybeg,$ylen @@";
+       }
+}
+
+/**
+ * A pseudo-formatter that just passes along the Diff::$edits array
+ * @addtogroup DifferenceEngine
+ */
+class ArrayDiffFormatter extends DiffFormatter
+{
+       function format($diff)
+       {
+               $oldline = 1;
+               $newline = 1;
+               $retval = array();
+               foreach($diff->edits as $edit)
+                       switch($edit->type)
+                       {
+                               case 'add':
+                                       foreach($edit->closing as $l)
+                                       {
+                                               $retval[] = array(
+                                                       'action' => 'add',
+                                                       'new'=> $l,
+                                                       'newline' => $newline++
+                                               );
+                                       }
+                                       break;
+                               case 'delete':
+                                       foreach($edit->orig as $l)
+                                       {
+                                               $retval[] = array(
+                                                       'action' => 'delete',
+                                                       'old' => $l,
+                                                       'oldline' => $oldline++,
+                                               );
+                                       }
+                                       break;
+                               case 'change':
+                                       foreach($edit->orig as $i => $l)
+                                       {
+                                               $retval[] = array(
+                                                       'action' => 'change',
+                                                       'old' => $l,
+                                                       'new' => $edit->closing[$i],
+                                                       'oldline' => $oldline++,
+                                                       'newline' => $newline++,
+                                               );
+                                       }
+                                       break;
+                               case 'copy':
+                                       $oldline += count($edit->orig);
+                                       $newline += count($edit->orig);
+                       }
+               return $retval;
+       }                       
+}
 
 /**
  *     Additions by Axel Boldt follow, partly taken from diff.php, phpwiki-1.3.3
index d32afc9..82f7d7e 100644 (file)
@@ -45,7 +45,7 @@ class ApiQueryRevisions extends ApiQueryBase {
                        $fld_comment = false, $fld_user = false, $fld_content = false;
 
        public function execute() {
-               $limit = $startid = $endid = $start = $end = $dir = $prop = $user = $excludeuser = $diffto = $difftoprev = null;
+               $limit = $startid = $endid = $start = $end = $dir = $prop = $user = $excludeuser = $diffto = $difftoprev = $diffformat = null;
                extract($this->extractRequestParams());
 
                // If any of those parameters are used, work in 'enumeration' mode.
@@ -87,7 +87,17 @@ class ApiQueryRevisions extends ApiQueryBase {
                $this->fld_size = $this->addFieldsIf('rev_len', isset ($prop['size']));
 
                if($diffto || $difftoprev)
-                       $this->formatter = new DiffFormatter;
+                       switch($diffformat)
+                       {
+                               case 'traditional':
+                                       $this->formatter = new DiffFormatter;
+                                       break;
+                               case 'unified':
+                                       $this->formatter = new UnifiedDiffFormatter;
+                                       break;
+                               case 'array':
+                                       $this->formatter = new ArrayDiffFormatter; 
+                       }
                if($diffto)
                {
                        global $wgContLang;
@@ -252,7 +262,14 @@ class ApiQueryRevisions extends ApiQueryBase {
                                $newText = explode("\n", $wgContLang->segmentForDiff($revtext));
                                $diff = new Diff($oldText, $newText);
                                $r['from'] = $previousRevID;
-                               ApiResult::setContent($r, $wgContLang->unsegmentForDiff($this->formatter->format($diff)));
+                               $formatted = $this->formatter->format($diff);
+                               if(!is_array($formatted))
+                                       ApiResult::setContent($r, $wgContLang->unsegmentForDiff($this->formatter->format($diff)));
+                               else
+                               {
+                                       $r['differences'] = $formatted;
+                                       $this->getResult()->setIndexedTagName($r['differences'], 'diff');
+                               } 
                                $this->diffArr[$revid] = $r;
                                                                
                                $previousRevID = $revid;
@@ -390,6 +407,14 @@ class ApiQueryRevisions extends ApiQueryBase {
                                ApiBase :: PARAM_TYPE => 'integer'
                        ),
                        'difftoprev' => false,
+                       'diffformat' => array(
+                               ApiBase :: PARAM_TYPE => array(
+                                       'traditional',
+                                       'unified',
+                                       'array',
+                               ),
+                               ApiBase ::PARAM_DFLT => 'unified'
+                       )
                );
        }
 
@@ -407,6 +432,7 @@ class ApiQueryRevisions extends ApiQueryBase {
                        'expandtemplates' => 'expand templates in revision content',
                        'diffto' => 'Revision number to compare all revisions with',
                        'difftoprev' => 'Diff each revision to the previous one (enum)',
+                       'diffformat' => 'Format to use for diffs',
                );
        }