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