+#!/usr/bin/perl
+# Ikiwiki Sweave-alike plugin
+# under the terms of the GPL version 2, or any later version at your
+# option.
+# Copyright 2012 by Don Armstrong <don@donarmstrong.com>.
+
+
+package IkiWiki::Plugin::sweavealike;
+
+=head1 NAME
+
+sweavealike -- A Sweave-alike plugin which allows for embedding R code in IkiWiki
+
+=head1 SYNOPSIS
+
+
+=head1 DESCRIPTION
+
+
+=head1 BUGS
+
+None known.
+
+=cut
+
+use warnings;
+use strict;
+
+use Statistics::R;
+
+use IkiWIki '3.00';
+
+my $id = "sweavealike";
+sub import {
+ hook(type => "preprocess", id => $id, call => \&preprocess);
+ hook(type => "preprocess", id => $id, call => \&preprocess_scan, scan => 1);
+ hook(type => "htmlize", id => $id, call => \&htmlize);
+ hook(type => "savestate", id => $id, call => \&savestate);
+}
+
+sub preprocess_scan {
+ my %param = @_;
+ # start the R process here for this page
+ if (not defined $pagestate{$param{page}}{$id}{R}) {
+ $pagestate{$param{page}}{$id}{R} = Statistics::R->new(shared => 1) or error("Unable to create an R process");
+ }
+}
+
+sub preprocess {
+ my %param = @_;
+
+ # we currently don't bother to support anything but outputing the
+ # entire segment of code and its R output
+
+ if (not exists $param{code} or not defined $param{code}) {
+ error("There wasn't any R code supplied");
+ }
+ my $code_result;
+ eval {
+ $code_result = $pagestate{$param{page}}{$id}{R}->run($param{code});
+ };
+ if ($@) {
+ error($@);
+ }
+ my $output;
+ if ($param{verbatim}) {
+ $output = $param{code};
+ $output =~ s/^/> /mg;
+ }
+ $output .= $code_result;
+ $output =~ s/^/ /mg;
+ return($output);
+}
+
+# stop any started R processes here
+sub htmlize {
+ my %param = @_;
+ if (exists $pagestate{$param{page}} and
+ exists $pagestate{$param{page}}{$id} and
+ exists $pagestate{$param{page}}{$id}{R}) {
+ if (defined $pagestate{$param{page}}{$id}{R}
+ and $pagestate{$param{page}}{$id}{R}->is_started()) {
+ $pagestate{$param{page}}{$id}{R}->stop();
+ }
+ delete $pagestate{$param{page}}{$id}{R};
+ }
+}
+
+sub savestate {
+ # make sure we never try to save an R process
+ for my $page (keys %pagestate) {
+ next unless exists $pagestate{$page}{$id};
+ next unless exists $pagestate{$page}{$id}{R};
+ if (defined $pagestate{$page}{$id}{R}
+ and $pagestate{$param{page}}{$id}{R}->is_started()) {
+ $pagestate{$page}{$id}{R}->stop;
+ }
+ delete $pagestate{$page}{$id}{R};
+ }
+}
+
+
+
+
+
+1;
+
+
+__END__
+
+
+
+
+
+
+
+