diff options
Diffstat (limited to 'IkiWiki/Plugin')
-rw-r--r-- | IkiWiki/Plugin/editdiff.pm | 69 |
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 |