summaryrefslogtreecommitdiff
path: root/IkiWiki/Plugin/editdiff.pm
blob: 9872e9686c2a3255d638968002a5d6339c1d20e2 (plain)
  1. #!/usr/bin/perl
  2. # This plugin adds a "Diff" button to the page edit form.
  3. package IkiWiki::Plugin::editdiff;
  4. use warnings;
  5. use strict;
  6. use IkiWiki 2.00;
  7. use HTML::Entities;
  8. use IPC::Open2;
  9. sub import { #{{{
  10. hook(type => "formbuilder_setup", id => "editdiff",
  11. call => \&formbuilder_setup);
  12. } #}}}
  13. sub diff ($$) { #{{{
  14. my $orig=shift;
  15. my $content=shift;
  16. my $sigpipe=0;
  17. $SIG{PIPE} = sub { $sigpipe=1; };
  18. my $pid = open2(*DIFFOUT, *DIFFIN, 'diff', '-u', $orig, '-');
  19. binmode($_, ':utf8') foreach (*DIFFIN, *DIFFOUT);
  20. print DIFFIN $content;
  21. close DIFFIN;
  22. my $ret='';
  23. while (<DIFFOUT>) {
  24. if (defined $ret) {
  25. $ret.=$_;
  26. }
  27. elsif (/^\@\@/) {
  28. $ret=$_;
  29. }
  30. }
  31. close DIFFOUT;
  32. waitpid $pid, 0;
  33. $SIG{PIPE}="default";
  34. return "couldn't run diff\n" if $sigpipe;
  35. return "<pre>".encode_entities($ret)."</pre>";
  36. } #}}}
  37. sub formbuilder_setup { #{{{
  38. my %params=@_;
  39. my $form=$params{form};
  40. return if defined ! $form->field("do") || $form->field("do") ne "edit";
  41. my $page=$form->field("page");
  42. $page = IkiWiki::possibly_foolish_untaint($page);
  43. return unless exists $pagesources{$page};
  44. push @{$params{buttons}}, "Diff";
  45. if ($form->submitted eq "Diff") {
  46. my $content=$form->field('editcontent');
  47. $content=~s/\r\n/\n/g;
  48. $content=~s/\r/\n/g;
  49. my $diff = diff(srcfile($pagesources{$page}), $content);
  50. $form->tmpl_param("page_preview", $diff);
  51. }
  52. } #}}}
  53. 1