]> sipb.mit.edu Git - ikiwiki.git/blobdiff - IkiWiki/Plugin/editdiff.pm
* Call the formbuilder hook for the edit page.
[ikiwiki.git] / IkiWiki / Plugin / editdiff.pm
diff --git a/IkiWiki/Plugin/editdiff.pm b/IkiWiki/Plugin/editdiff.pm
new file mode 100644 (file)
index 0000000..46eb116
--- /dev/null
@@ -0,0 +1,69 @@
+#!/usr/bin/perl
+# This plugin adds a "Diff" button to the page edit form.
+package IkiWiki::Plugin::editdiff;
+
+use warnings;
+use strict;
+use IkiWiki 2.00;
+use HTML::Entities;
+use IPC::Open2;
+
+sub import { #{{{
+       hook(type => "formbuilder_setup", id => "editdiff",
+               call => \&formbuilder_setup);
+} #}}}
+
+sub diff ($$) { #{{{
+       my $orig=shift;
+       my $content=shift;
+
+       my $sigpipe=0;
+       $SIG{PIPE} = sub { $sigpipe=1; };
+
+       my $pid = open2(*DIFFOUT, *DIFFIN, 'diff', '-u', $orig, '-');
+       binmode($_, ':utf8') foreach (*DIFFIN, *DIFFOUT);
+
+       print DIFFIN $content;
+       close DIFFIN;
+       my $ret;
+       while (<DIFFOUT>) {
+               if (defined $ret) {
+                       $ret.=$_;
+               }
+               elsif (/^\@\@/) {
+                       $ret=$_;
+               }
+       }
+       close DIFFOUT;
+       waitpid $pid, 0;
+
+       $SIG{PIPE}="default";
+       return "couldn't run diff\n" if $sigpipe;
+
+       return "<pre>".encode_entities($ret)."</pre>";
+} #}}}
+
+sub formbuilder_setup { #{{{
+       my %params=@_;
+       my $form=$params{form};
+       my $page=$form->field("page");
+
+       return if $form->title ne "editpage"
+                 || $form->field("do") ne "edit";
+
+       $page = IkiWiki::titlepage(IkiWiki::possibly_foolish_untaint($page));
+       return unless exists $pagesources{$page};
+
+       push @{$params{buttons}}, "Diff";
+
+       if ($form->submitted eq "Diff") {
+               my $content=$form->field('editcontent');
+               $content=~s/\r\n/\n/g;
+               $content=~s/\r/\n/g;
+
+               my $diff = diff(srcfile($pagesources{$page}), $content);
+               $form->tmpl_param("page_preview", $diff);
+       }
+} #}}}
+
+1