]> sipb.mit.edu Git - ikiwiki.git/commitdiff
add postsparkline plugin, providing sparkliney stats goodness for blog
authorjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Sun, 11 Mar 2007 00:24:31 +0000 (00:24 +0000)
committerjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Sun, 11 Mar 2007 00:24:31 +0000 (00:24 +0000)
posts

IkiWiki/Plugin/postsparkline.pm [new file with mode: 0644]
debian/changelog
doc/plugins/postsparkline.mdwn [new file with mode: 0644]

diff --git a/IkiWiki/Plugin/postsparkline.pm b/IkiWiki/Plugin/postsparkline.pm
new file mode 100644 (file)
index 0000000..2bc9308
--- /dev/null
@@ -0,0 +1,123 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::postsparkline;
+
+use warnings;
+use strict;
+use IkiWiki;
+
+sub import { #{{{
+       IkiWiki::loadplugin('sparkline');
+       hook(type => "preprocess", id => "postsparkline", call => \&preprocess);
+} # }}}
+
+sub preprocess (@) { #{{{
+       my %params=@_;
+
+       if (! exists $params{max}) {
+               $params{max}=100;
+       }
+
+       if (! exists $params{pages}) {
+               return "";
+       }
+
+       if (! exists $params{formula}) {
+               return "[[postsparkline ".gettext("missing formula")."]]";
+       }
+       my $formula=$params{formula};
+       $formula=~s/[^a-zA-Z0-9]*//g;
+       $formula=IkiWiki::possibly_foolish_untaint($formula);
+       if (! length $formula ||
+           ! IkiWiki::Plugin::postsparkline::formula->can($formula)) {
+               return "[[postsparkline ".gettext("unknown formula")."]]";
+       }
+
+       add_depends($params{page}, $params{pages});
+
+       my @list;
+       foreach my $page (keys %pagesources) {
+               next if $page eq $params{page};
+               if (pagespec_match($page, $params{pages}, $params{page})) {
+                       push @list, $page;
+               }
+       }
+       
+       @list = sort { $IkiWiki::pagectime{$b} <=> $IkiWiki::pagectime{$a} } @list;
+
+       delete $params{pages};
+       delete $params{formula};
+       my @data=eval qq{IkiWiki::Plugin::postsparkline::formula::$formula(\\\%params, \@list)};
+       if ($@) {
+               return "[[postsparkline error $@]]";
+       }
+       return IkiWiki::Plugin::sparkline::preprocess(%params, 
+               map { $_ => "" } reverse @data);
+} # }}}
+
+sub perfoo ($@) {
+       my $sub=shift;
+       my $params=shift;
+       
+       my $max=$params->{max};
+       my ($first, $prev, $cur);
+       my $count=0;
+       my @data;
+       foreach (@_) {
+               $cur=$sub->($IkiWiki::pagectime{$_});
+               if (defined $prev) {
+                       if ($prev != $cur) {
+                               push @data, "$prev,$count";
+                               $count=0;
+                               last if --$max <= 0;
+
+                               for ($cur+1 .. $prev-1) {
+                                       push @data, "$_,0";
+                                       last if --$max == 0;
+                               }
+                       }
+               }
+               else {
+                       $first=$cur;
+               }
+               $count++;
+               $prev=$cur;
+       }
+
+       return @data;
+}
+
+package IkiWiki::Plugin::postsparkline::formula;
+
+sub peryear (@) {
+       return IkiWiki::Plugin::postsparkline::perfoo(sub {
+               return (localtime $_[0])[5];
+       }, @_);
+}
+
+sub permonth (@) {
+       return IkiWiki::Plugin::postsparkline::perfoo(sub {
+               my ($month, $year)=(localtime $_[0])[4,5];
+               return $year*12+$month;
+       }, @_);
+}
+
+sub perday (@) {
+       return IkiWiki::Plugin::postsparkline::perfoo(sub {
+               my ($year, $yday)=(localtime $_[0])[5,7];
+               return $year*365+$yday;
+       }, @_);
+}
+
+sub interval ($@) {
+       my $params=shift;
+
+       my $max=$params->{max};
+       my @data;
+       for (my $i=1; $i < @_; $i++) {
+               push @data, $IkiWiki::pagectime{$_[$i-1]} - $IkiWiki::pagectime{$_[$i]};
+               last if --$max <= 0;
+       }
+       return @data;
+}
+
+1
index faddbb983c82d50441942f01a1f9eb86fa26705d..f144432177d19ebe9ce7a1143a213e12fe8ec9e7 100644 (file)
@@ -13,6 +13,7 @@ ikiwiki (1.45) UNRELEASED; urgency=low
     image using width and height attributes.
   * Also fixes img preview display, the links were wrong in preview before.
   * Add a sparkline plugin.
+  * Add a postsparkline plugin.
   * The slash escaping when adding to a blog from the CGI was not working
     since it ended up being double-escaped. Instead, just remove slashes.
   * Fix some nasty issues with page name escaping during previewing
diff --git a/doc/plugins/postsparkline.mdwn b/doc/plugins/postsparkline.mdwn
new file mode 100644 (file)
index 0000000..a85d7e8
--- /dev/null
@@ -0,0 +1,46 @@
+[[template id=plugin name=postsparkline author="[[Joey]]"]]
+[[tag type/chrome]]
+
+This plugin uses the [[sparkline]] plugin to create a sparkline of
+statistics about a set of pages, such as posts to a blog.
+
+# examples
+
+       Post interval: 
+       \[[postsparkline pages="blog/* and !*/Discussion" max=100
+       formula=interval style=bar barwidth=2 barspacing=1 height=13]]
+       
+       Posts per month this year: 
+       \[[postsparkline pages="blog/* and !*/Discussion" max=12
+       formula=permonth style=bar barwidth=2 barspacing=1 height=13]]
+
+# usage
+
+All options aside fron the `pages`, `max`, and `forumla` options are passed
+on to the sparkline plugin.
+
+You don't need to specify any data points (though you can if you want to).
+Instead, data points are automatically generated based on the creation
+times of pages matched by the specified `pages` [[PageSpec]]. A maximum of
+`max` data points will be generated.
+
+The `formula` parameter controls the formula used to generate data points.
+Available forumlae:
+
+* `interval` - The height of each point represents how long it has been
+  since the previous post.
+* `perday` - Each point represents a day; the height represents how
+  many posts were made that day.
+* `permonth` - Each point represents a month; the height represents how
+  many posts were made that month.
+* `peryear` - Each point represents a day; the height represents how
+  many posts were made that year.
+
+# adding formulae
+
+Additional formulae can be added without modifying this plugin by writing
+plugins that register functions in the
+`IkiWiki::Plugin::postsparkline::formula` namespace. These functions will
+receive on input a reference to a hash of parameters, and a sorted list of
+pages (newest pages first), and should return a list of data points for
+the sparkline plugin.