]> git.donarmstrong.com Git - ikiwiki_plugins.git/commitdiff
more work on the figures
authorDon Armstrong <don@donarmstrong.com>
Thu, 22 Mar 2012 19:14:27 +0000 (12:14 -0700)
committerDon Armstrong <don@donarmstrong.com>
Thu, 22 Mar 2012 19:14:27 +0000 (12:14 -0700)
document options for figures

sweavealike.pm

index d330a58706919225541363b9ec039b5acca261f0..d58ad6822c774b62ba597062699399f007abd592 100644 (file)
@@ -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<img class="sweavealike" src=").urlto($image_loc,$param{destpage}).qq(" />);
     }
     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