#!/usr/bin/perl -wT # # TWiki Collaboration Platform, http://TWiki.org/ # # Copyright (C) 1999-2003 Peter Thoeny, peter@thoeny.com # # For licensing info read license.txt file in the TWiki root. # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details, published at # http://www.gnu.org/copyleft/gpl.html # Set library paths in @INC, at compile time BEGIN { unshift @INC, '.'; require 'setlib.cfg'; } use CGI::Carp qw(fatalsToBrowser); use CGI; use TWiki; $query= new CGI; &main(); # ========================= sub renderCellData { my( $data, $topic ) = @_; if( $data ) { $data = &TWiki::handleCommonTags( $data, $topic ); $data = &TWiki::getRenderedVersion( $data ); if( $data =~ m/<\/?(th|td|table)/i ) { # data has or , need to fix my $bTable = ( $data =~ s/( $eTable ) { for( $i = $eTable; $i < $bTable; $i++ ) { $data .= "
"; } } elsif( $bTable < $eTable ) { for( $i = $bTable; $i < $eTable; $i++ ) { $data = "\n$data"; } } elsif( ( $bTable == 0 ) && ( $eTable == 0 ) ) { $data = "\n
$data\n
"; } } } return $data; } # ========================= sub renderRevisionDiff { my( $text, $topic ) = @_; $text =~ s/\r//go; # cut CR my $result = "\n
"; my $data = ""; foreach( split( /\n/, $text ) ) { if( /^[0-9]/ ) { $data = renderCellData( $data, $topic ); $result .= $data; $data = ""; s/^([0-9\,]+)d([0-9\,]+)/\n<\/td><\/tr>\n
Deleted: <\/b><\/td><\/tr>\n
<
<<\/td>
/go; s/^([0-9\,]+)a([0-9\,]+)/\n<\/td><\/tr>\n
Added: <\/b><\/td><\/tr>\n
>
><\/td>
/go; s/^([0-9\,]+)c([0-9\,]+)/\n<\/td><\/tr>\n
Changed: <\/b><\/td><\/tr>\n
<
<<\/td>
/go; $result .= $_; } elsif( /^[<>]/ ) { s/^[<>] (.*)/$1/go; $data .= "\n$_"; } elsif( /^--*/ ) { $data = renderCellData( $data, $topic ); $result .= $data; $data = ""; $result .= "\n
>
>
\n"; } } $data = renderCellData( $data, $topic ); $result .= $data; $data = ""; $text = "$result<\/td><\/tr>\n<\/table>"; return $text; } sub getRevInfo { my( $web, $rev, $topic, $short ) = @_; my( $date, $user ) = &TWiki::Store::getRevisionInfo( $web, $topic, "1.$rev", 1 ); $user = TWiki::getRenderedVersion( TWiki::userToWikiName( $user ) ); if( $short ) { # cut time $date =~ s/ \- [0-9]*\:[0-9]+$//go; # eliminate white space to prevent wrap around in HR table: $date =~ s/ /\ \;/go; } else { $date .= " GMT"; } my $revInfo = "$date - $user"; $revInfo =~ s/[\n\r]*//go; return $revInfo; } sub main { my $thePathInfo = $query->path_info(); my $theRemoteUser = $query->remote_user(); my $theTopic = $query->param('topic'); my $theUrl = $query->url; ( $topic, $webName, $scriptUrlPath, $userName ) = &TWiki::initialize( $thePathInfo, $theRemoteUser, $theTopic, $theUrl, $query ); my $tmpl = "", $text = "", $diff = ""; my $rev1 = $query->param( "rev1" ); my $rev2 = $query->param( "rev2" ); my $maxrev= 1; my $i = $maxrev, $j = $maxrev; my $revTitle1 = "", $revTitle2 = ""; my $revInfo1 = "", $revInfo2 = ""; my $isMultipleDiff = 0; if( ! &TWiki::Store::webExists( $webName ) ) { my $url = &TWiki::getOopsUrl( $webName, $topic, "oopsnoweb" ); TWiki::redirect( $query, $url ); return; } # get view template, standard view or a view with a different skin my $skin = $query->param( "skin" ) || &TWiki::Prefs::getPreferencesValue( "SKIN" ); $tmpl = &TWiki::Store::readTemplate( "rdiff", $skin ); $tmpl =~ s/\%META{.*?}\%//go; # remove %META{"parent"}% my( $before, $difftmpl, $after) = split( /%REPEAT%/, $tmpl); my $topicExists = &TWiki::Store::topicExists( $webName, $topic ); if( $topicExists ) { $maxrev = &TWiki::Store::getRevisionNumber( $webName, $topic ); $maxrev =~ s/r?1\.//go; # cut 'r' and major if( ! $rev1 ) { $rev1 = 0; } if( ! $rev2 ) { $rev2 = 0; } $rev1 =~ s/r?1\.//go; # cut 'r' and major $rev2 =~ s/r?1\.//go; # cut 'r' and major if( $rev1 < 1 ) { $rev1 = $maxrev; } if( $rev1 > $maxrev ) { $rev1 = $maxrev; } if( $rev2 < 1 ) { $rev2 = 1; } if( $rev2 > $maxrev ) { $rev2 = $maxrev; } $revTitle1 = "r1.$rev1"; $revInfo1 = getRevInfo( $webName, $rev1, $topic ); if( $rev1 != $rev2 ) { $revTitle2 = "r1.$rev2"; $revInfo2 = getRevInfo( $webName, $rev2, $topic ); } } else { $rev1 = 1; $rev2 = 1; } # check access permission my $wikiUserName = &TWiki::userToWikiName( $userName ); my $viewAccessOK = &TWiki::Access::checkAccessPermission( "view", $wikiUserName, "", $topic, $webName ); if( ( $TWiki::readTopicPermissionFailed ) || ( ! $viewAccessOK ) ) { my $url = &TWiki::getOopsUrl( $webName, $topic, "oopsaccessview" ); TWiki::redirect( $query, $url ); return; } # format "before" part $before =~ s/%REVTITLE1%/$revTitle1/go; $before =~ s/%REVTITLE2%/$revTitle2/go; $before = &TWiki::handleCommonTags( $before, $topic ); $before = &TWiki::getRenderedVersion( $before ); $before =~ s|( ?) *\n?|$1|gois; # remove tags (PTh 06 Nov 2000) &TWiki::writeHeader( $query ); print $before; # do one or more diffs $difftmpl = &TWiki::handleCommonTags( $difftmpl, $topic ); if( $topicExists ) { my $r1 = $rev1, $r2 = $rev2, $rInfo = ""; if( $r1 > $r2 + 1) { $r2 = $r1 - 1; $isMultipleDiff = 1; } do { $diff = $difftmpl; $diff =~ s/%REVTITLE1%/r1\.$r1/go; $rInfo = getRevInfo( $webName, $r1, $topic, 1 ); $diff =~ s/%REVINFO1%/$rInfo/go; $text = &TWiki::Store::getRevisionDiff( $webName, $topic, "1.$r2", "1.$r1" ); $text = renderRevisionDiff( $text, $topic ); $diff =~ s/%TEXT%/$text/go; $diff =~ s|( ?) *\n?|$1|gois; # remove tags (PTh 06 Nov 2000) print $diff; $r1 = $r1 - 1; $r2 = $r2 - 1; if( $r2 < 1 ) { $r2 = 1; } } while( ( $r1 > $rev2 ) || ( $r1 == 1 ) ); } else { $diff = $difftmpl; $diff =~ s/%REVTITLE1%/$revTitle1/go; $diff =~ s/%REVTITLE2%/$revTitle2/go; $diff =~ s/%TEXT%//go; $diff =~ s|( ?) *\n?|$1|gois; # remove tags (PTh 06 Nov 2000) print $diff; } if( $TWiki::doLogTopicRdiff ) { # write log entry &TWiki::Store::writeLog( "rdiff", "$webName.$topic", "r1.$rev1 r1.$rev2" ); } # format "after" part $i = $maxrev; $j = $maxrev; my $revisions = ""; my $breakRev = 0; if( ( $TWiki::numberOfRevisions > 0 ) && ( $TWiki::numberOfRevisions < $maxrev ) ) { $breakRev = $maxrev - $TWiki::numberOfRevisions + 1; } while( $i > 0 ) { $revisions .= " | r1.$i"; if( $i != 1 ) { if( $i == $breakRev ) { # Now obsolete because of 'More' link # $revisions = "$revisions | >..."; $i = 1; } else { if( ( $i == $rev1 ) && ( !$isMultipleDiff ) ) { $revisions .= " | >"; } else { $j = $i - 1; $revisions .= " | >"; } } } $i = $i - 1; } $after =~ s/%REVISIONS%/$revisions/go; $after =~ s/%CURRREV%/1.$rev1/go; $after =~ s/%MAXREV%/1.$maxrev/go; $after =~ s/%REVTITLE1%/$revTitle1/go; $after =~ s/%REVINFO1%/$revInfo1/go; $after =~ s/%REVTITLE2%/$revTitle2/go; $after =~ s/%REVINFO2%/$revInfo2/go; $after = &TWiki::handleCommonTags( $after, $topic ); $after = &TWiki::getRenderedVersion( $after ); $after =~ s|( ?) *\n?|$1|gois; # remove tags (PTh 06 Nov 2000) print $after; }