From 537f7ea5b3e2b0effa2b0ccbc6acd2cfc12e84d2 Mon Sep 17 00:00:00 2001 From: Roan Kattouw Date: Tue, 27 Nov 2007 21:36:43 +0000 Subject: [PATCH] API: * Adding rvdiffformat parameter to prop=revisions * Creating formatters for unified (UnifiedDiffFormatter) and array (ArrayDiffFormatter) diffs --- RELEASE-NOTES | 1 + includes/AutoLoader.php | 2 + includes/DifferenceEngine.php | 78 ++++++++++++++++++++++++++++++ includes/api/ApiQueryRevisions.php | 32 ++++++++++-- 4 files changed, 110 insertions(+), 3 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index b6baf156c6..e3a8ae0af9 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -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 === diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index 966f9afc1c..afed43d83d 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -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', diff --git a/includes/DifferenceEngine.php b/includes/DifferenceEngine.php index 348fe0a9ad..2730c98cff 100644 --- a/includes/DifferenceEngine.php +++ b/includes/DifferenceEngine.php @@ -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 diff --git a/includes/api/ApiQueryRevisions.php b/includes/api/ApiQueryRevisions.php index d32afc9fb0..82f7d7ef73 100644 --- a/includes/api/ApiQueryRevisions.php +++ b/includes/api/ApiQueryRevisions.php @@ -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', ); } -- 2.20.1