From 77890a593855f45d0c70b8bfb29c91358875909e Mon Sep 17 00:00:00 2001 From: Don Armstrong Date: Thu, 22 Mar 2012 12:14:27 -0700 Subject: [PATCH] more work on the figures document options for figures --- sweavealike.pm | 111 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 91 insertions(+), 20 deletions(-) diff --git a/sweavealike.pm b/sweavealike.pm index d330a58..d58ad68 100644 --- a/sweavealike.pm +++ b/sweavealike.pm @@ -13,13 +13,66 @@ sweavealike -- A Sweave-alike plugin which allows for embedding R code in IkiWik =head1 SYNOPSIS +sweavealike allows you to embed R code in IkiWiki. + + +[[!sweavealike code=''' +a <- 1 +a <- a*a+10 +print(a) +''']] + =head1 DESCRIPTION +=head2 Available options + +=over + +=item code + +R code to execute. Required to be present. [If you didn't want to +execute R code, why would you use this directive?] + +=item echo + +Echo the R code. [Basically, this escapes the code with >, and then +adds spaces so that the output is interpreted as a code fragment.] + +=item nooutput + +Suppress all non-figure output + +=item results + +Defaults to show the results (what R wrote to stdout) of a particular +piece of code + +=item fig + +If present, code is assumed to produce a figure which is automatically +included inline + +=item width + +Integer width of included figure; defaults to 400 + +=item height + +Integer height of included figure; defaults to 400 + +=back + =head1 BUGS -None known. +R is a complete language, and no attempt is made to control what you +can do. Reading and writing arbitrary files, as well as exhausting +available memory and CPU are all trivially possible. Thus, you should +NEVER use this plugin on a publicly editable IkiWiki instance. + +You should be able to refer to previously created figures without +rerunning the code. =cut @@ -42,7 +95,7 @@ sub import { } sub getsetup { - return(plugin => {safe => 1, + return(plugin => {safe => 0, rebuild => 1, section => "misc", link => "http://git.donarmstrong.com/?p=ikiwiki_plugins.git;a=blob;f=sweavealike.pm;hb=HEAD", @@ -52,8 +105,7 @@ sub getsetup { } sub code_md5 { - my ($code) = @_; - return(md5_hex(decode('utf8',$code))); + return(md5_hex(map {decode('utf8',$_)} @_)); } sub preprocess { @@ -72,18 +124,28 @@ sub preprocess { error("There wasn't any R code supplied"); } - $param{width} = '400' unless exists $param{width} and defined $param{width}; - $param{height} = '400' unless exists $param{height} and defined $param{height}; - for (qw(width height)) { - if ($param{$_} !~ /^\d+$/) { - error("invalid $_; must be an integer: $param{$_}"); + my $image_loc + if (exists $param{fig}) { + $pagestate{$param{page}}{$id}{fignum}++; + $param{width} = '400' unless exists $param{width} and defined $param{width}; + $param{height} = '400' unless exists $param{height} and defined $param{height}; + for (qw(width height)) { + if ($param{$_} !~ /^\d+$/) { + error("invalid $_; must be an integer: $param{$_}"); + } + } + # because even if the code is duplicated, the figure could still be the same. + my $md5 = code_md5($param{code},$param{width},$param{height},$pagestate{$param{page}}{$id}{fignum}); + $image_loc = "$param{page}/${md5}.png"; + my $image_loc_esc = $image_loc; + $image_loc_esc =~ s/"/\\"/g; + will_render($param{page},$image_loc); + eval { + $pagestate{$param{page}}{$id}{R}->run(qq{png(filename="$image_loc_esc",width=$param{width},height=$param{height});}); + }; + if ($@) { + error("code 'png(filename="$image_loc_esc",width=$param{width},height=$param{height});' (from internal figure handling) produced error '$@'"); } - } - if (exists $param{picture}) { - my $md5 = code_md5($param{code}."width=$param{width}height=$param{height}"); - my $page_esc = $params->{page}; - $page_esc =~ s/"/\\"/g; - $pagestate{$param{page}}{$id}{R}->run(qq{png(filename="$page_esc",width=$param{width},height=$param{height});}); } my $code_result; eval { @@ -92,19 +154,28 @@ sub preprocess { if ($@) { error("code '$param{code}' produced error '$@'"); } - if (exists $param{picture}) { - $pagestate{$param{page}}{$id}{R}->run(qq{dev.off();}); + my $output = ''; + my $fig_output = ''; + if (exists $param{fig}) { + eval { + $pagestate{$param{page}}{$id}{R}->run(qq{dev.off();}); + }; + if ($@) { + error("code 'dev.off()' (from internal figure handling) produced error '$@'"); + } + $fig_output = qq(\n); } if (exists $param{nooutput}) { - return(''); + return($output.$fig_output); } - my $output = ''; if (exists $param{echo}) { $output .= $param{code}; $output =~ s/^/> /mg; $output .= "\n"; } - if (exists $param{results}) { + if (not exists $param{results} or + (defined $param{results} and + $param{results} !~ /^(hide|false)$/i;)) { $output .= $code_result; } if (exists $param{echo} or -- 2.39.2