summaryrefslogtreecommitdiff
path: root/IkiWiki/Plugin/editdiff.pm
blob: f5d7837fc4c4712de2b693497ce3dd1b7a977b59 (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 => "getsetup", id => "editdiff", call => \&getsetup);
  11. hook(type => "formbuilder_setup", id => "editdiff",
  12. call => \&formbuilder_setup);
  13. } #}}}
  14. sub getsetup () { #{{{
  15. return
  16. plugin => {
  17. safe => 1,
  18. rebuild => 0,
  19. },
  20. } #}}}
  21. sub diff ($$) { #{{{
  22. my $orig=shift;
  23. my $content=shift;
  24. my $sigpipe=0;
  25. $SIG{PIPE} = sub { $sigpipe=1; };
  26. my $pid = open2(*DIFFOUT, *DIFFIN, 'diff', '-u', $orig, '-');
  27. binmode($_, ':utf8') foreach (*DIFFIN, *DIFFOUT);
  28. print DIFFIN $content;
  29. close DIFFIN;
  30. my $ret='';
  31. while (<DIFFOUT>) {
  32. if (defined $ret) {
  33. $ret.=$_;
  34. }
  35. elsif (/^\@\@/) {
  36. $ret=$_;
  37. }
  38. }
  39. close DIFFOUT;
  40. waitpid $pid, 0;
  41. $SIG{PIPE}="default";
  42. return "couldn't run diff\n" if $sigpipe;
  43. return "<pre>".encode_entities($ret)."</pre>";
  44. } #}}}
  45. sub formbuilder_setup { #{{{
  46. my %params=@_;
  47. my $form=$params{form};
  48. return if ! defined $form->field("do") || $form->field("do") ne "edit";
  49. my $page=$form->field("page");
  50. $page = IkiWiki::possibly_foolish_untaint($page);
  51. return unless exists $pagesources{$page};
  52. push @{$params{buttons}}, "Diff";
  53. if ($form->submitted eq "Diff") {
  54. my $content=$form->field('editcontent');
  55. $content=~s/\r\n/\n/g;
  56. $content=~s/\r/\n/g;
  57. my $diff = diff(srcfile($pagesources{$page}), $content);
  58. $form->tmpl_param("page_preview", $diff);
  59. }
  60. } #}}}
  61. 1