diff.pl 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. # Copyright (C) 2014 Alex-Daniel Jakimenko <alex.jakimenko@gmail.com>
  2. # Copyright (C) 2014 Alex Schroeder <alex@gnu.org>
  3. # This program is free software: you can redistribute it and/or modify it under
  4. # the terms of the GNU General Public License as published by the Free Software
  5. # Foundation, either version 3 of the License, or (at your option) any later
  6. # version.
  7. #
  8. # This program is distributed in the hope that it will be useful, but WITHOUT
  9. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  10. # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  11. #
  12. # You should have received a copy of the GNU General Public License along with
  13. # this program. If not, see <http://www.gnu.org/licenses/>.
  14. use strict;
  15. use v5.10;
  16. AddModuleDescription('diff.pl', 'Diff Action Extension');
  17. our ($q, %Action, @IndexList, @MyRules, $TempDir);
  18. push(@MyRules, \&DiffActionRule);
  19. $Action{pagediff} = \&DoDiffAction;
  20. sub DiffActionRule {
  21. return PrintDiffActionChooser($3) if (m/\G(&lt;diff( (.*))&gt;)/cgi);
  22. return; # the rule didn't match
  23. }
  24. sub DoDiffAction {
  25. print GetHeader('', T('Page diff'), '');
  26. my $page1 = GetParam('page1');
  27. my $page2 = GetParam('page2');
  28. my $pattern = GetParam('pattern');
  29. $pattern ||= '.*';
  30. print PrintDiffActionChooser($pattern);
  31. ValidIdOrDie($page1);
  32. ValidIdOrDie($page2);
  33. my $diff = DoUnifiedDiff("1\n \n" . GetPageContent($page1), "2\n \n" . GetPageContent($page2)); # add extra lines, otherwise diff between identical files will print nothing # TODO fix this, otherwise one day this will fail...
  34. $diff = QuoteHtml($diff);
  35. $diff =~ tr/\r//d; # TODO is this required? # probably not
  36. for (split /\n/, $diff) {
  37. s/(^.)//;
  38. my $type = $1;
  39. if ($type eq '+') {
  40. print '<span class="diffactionnew">' . $type;
  41. } elsif ($type eq '-') {
  42. print '<span class="diffactionold">' . $type;
  43. }
  44. ApplyRules($_);
  45. print '</span>' if $type =~ /[+-]/;
  46. print '<br/>';
  47. }
  48. PrintFooter();
  49. }
  50. sub PrintDiffActionChooser {
  51. my $pattern = shift;
  52. $pattern ||= '.*';
  53. my @chosenPages = ();
  54. for (@IndexList) {
  55. push @chosenPages, $_ if m/$pattern/;
  56. }
  57. return GetFormStart(undef, 'get', 'pagediff')
  58. . GetHiddenValue('action', 'pagediff')
  59. . GetHiddenValue('pattern', $pattern)
  60. . $q->popup_menu(-name=>'page1', -values=>\@chosenPages) . ' '
  61. . $q->popup_menu(-name=>'page2', -values=>\@chosenPages) . ' '
  62. . $q->submit(-name=>'', -value=>T('Diff'))
  63. . $q->end_form();
  64. }
  65. sub DoUnifiedDiff { # copied from DoDiff
  66. CreateDir($TempDir);
  67. my $oldName = "$TempDir/old";
  68. my $newName = "$TempDir/new";
  69. RequestLockDir('diff') or return '';
  70. WriteStringToFile($oldName, $_[0]);
  71. WriteStringToFile($newName, $_[1]);
  72. my $diff_out = decode_utf8(`diff -U 99999 -- \Q$oldName\E \Q$newName\E | tail -n +7`); # should be +4, but we always add extra line # TODO that workaround is ugly, fix it!
  73. $diff_out =~ s/\n\K\\ No newline.*\n//g; # Get rid of common complaint.
  74. ReleaseLockDir('diff');
  75. # No need to unlink temp files--next diff will just overwrite.
  76. return $diff_out;
  77. }