force rebuild for theme change
[ikiwiki] / IkiWiki / Plugin / editdiff.pm
1 #!/usr/bin/perl
2 # This plugin adds a "Diff" button to the page edit form.
3 package IkiWiki::Plugin::editdiff;
4
5 use warnings;
6 use strict;
7 use IkiWiki 3.00;
8 use HTML::Entities;
9 use IPC::Open2;
10
11 sub import {
12         hook(type => "getsetup", id => "editdiff", call => \&getsetup);
13         hook(type => "formbuilder_setup", id => "editdiff",
14                 call => \&formbuilder_setup);
15 }
16
17 sub getsetup () {
18         return
19                 plugin => {
20                         safe => 1,
21                         rebuild => 0,
22                         section => "web",
23                 },
24 }
25
26 sub diff ($$) {
27         my $orig=shift;
28         my $content=shift;
29
30         my $sigpipe=0;
31         $SIG{PIPE} = sub { $sigpipe=1; };
32
33         my $pid = open2(*DIFFOUT, *DIFFIN, 'diff', '-u', $orig, '-');
34         binmode($_, ':utf8') foreach (*DIFFIN, *DIFFOUT);
35
36         print DIFFIN $content;
37         close DIFFIN;
38         my $ret='';
39         while (<DIFFOUT>) {
40                 if (defined $ret) {
41                         $ret.=$_;
42                 }
43                 elsif (/^\@\@/) {
44                         $ret=$_;
45                 }
46         }
47         close DIFFOUT;
48         waitpid $pid, 0;
49
50         $SIG{PIPE}="default";
51         return "couldn't run diff\n" if $sigpipe;
52
53         return "<pre>".encode_entities($ret)."</pre>";
54 }
55
56 sub formbuilder_setup {
57         my %params=@_;
58         my $form=$params{form};
59
60         return if ! defined $form->field("do") || $form->field("do") ne "edit";
61
62         my $page=$form->field("page");
63         $page = IkiWiki::possibly_foolish_untaint($page);
64         return unless exists $pagesources{$page};
65
66         push @{$params{buttons}}, "Diff";
67
68         if ($form->submitted eq "Diff") {
69                 my $content=$form->field('editcontent');
70                 $content=~s/\r\n/\n/g;
71                 $content=~s/\r/\n/g;
72
73                 my $diff = diff(srcfile($pagesources{$page}), $content);
74                 $form->tmpl_param("page_diff", $diff);
75         }
76 }
77
78 1