<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">#!/usr/bin/perl
# This plugin adds a "Diff" button to the page edit form.
package IkiWiki::Plugin::editdiff;

use warnings;
use strict;
use IkiWiki 3.00;
use HTML::Entities;
use IPC::Open2;

sub import {
	hook(type =&gt; "getsetup", id =&gt; "editdiff", call =&gt; \&amp;getsetup);
	hook(type =&gt; "formbuilder_setup", id =&gt; "editdiff",
		call =&gt; \&amp;formbuilder_setup);
}

sub getsetup () {
	return
		plugin =&gt; {
			safe =&gt; 1,
			rebuild =&gt; 0,
		},
}

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 (&lt;DIFFOUT&gt;) {
		if (defined $ret) {
			$ret.=$_;
		}
		elsif (/^\@\@/) {
			$ret=$_;
		}
	}
	close DIFFOUT;
	waitpid $pid, 0;

	$SIG{PIPE}="default";
	return "couldn't run diff\n" if $sigpipe;

	return "&lt;pre&gt;".encode_entities($ret)."&lt;/pre&gt;";
}

sub formbuilder_setup {
	my %params=@_;
	my $form=$params{form};

	return if ! defined $form-&gt;field("do") || $form-&gt;field("do") ne "edit";

	my $page=$form-&gt;field("page");
	$page = IkiWiki::possibly_foolish_untaint($page);
	return unless exists $pagesources{$page};

	push @{$params{buttons}}, "Diff";

	if ($form-&gt;submitted eq "Diff") {
		my $content=$form-&gt;field('editcontent');
		$content=~s/\r\n/\n/g;
		$content=~s/\r/\n/g;

		my $diff = diff(srcfile($pagesources{$page}), $content);
		$form-&gt;tmpl_param("page_preview", $diff);
	}
}

1
</pre></body></html>