summaryrefslogtreecommitdiff
path: root/IkiWiki/Plugin
diff options
context:
space:
mode:
Diffstat (limited to 'IkiWiki/Plugin')
-rw-r--r--IkiWiki/Plugin/editdiff.pm69
1 files changed, 69 insertions, 0 deletions
diff --git a/IkiWiki/Plugin/editdiff.pm b/IkiWiki/Plugin/editdiff.pm
new file mode 100644
index 000000000..46eb1168e
--- /dev/null
+++ b/IkiWiki/Plugin/editdiff.pm
@@ -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