added own PmWiki recipes

master
Fabien Benetou 13 years ago committed by utopiah
parent 0cc6728257
commit 5bf8e3fded
  1. 394
      cookbook/behavior_recall.php
  2. 75
      cookbook/coeditions.php
  3. 162
      cookbook/groupkeypages.php
  4. 50
      cookbook/groupstats.php
  5. 386
      cookbook/memorization.php
  6. 218
      cookbook/pim_functions.php
  7. 109
      cookbook/wikibrainmapping.php

@ -0,0 +1,394 @@
<?php if (!defined('PmWiki')) exit();
/*
inspired by PageFeed by Daniel Roesler (diafygi)
conversation array imported from it
*/
## Recipe version information
$RecipeInfo['BehaviorRecall']['Version'] = '2011-01-02';
## Add action for pagefeed
SDV($HandleActions['recall'], 'BehaviorRecall');
function addDate_BehaviorRecall($date,$day)//add days
{
$sum = strtotime(date("Y-m-d", strtotime("$date")) . " +$day days");
$dateTo=date('Y-m-d',$sum);
return $dateTo;
}
function convertDate_BehaviorRecall($date) {
return preg_replace("/(\d+)\/(\d+)\/(\d+)/",'$3-$2-$1',$date);
}
## Create feed from page history
function BehaviorRecall($pagename, $auth = 'read') {
global $FarmD, $WikiTitle, $ScriptUrl;
$feedfile = $FarmD."/pub/recallfeed.xml"; #change to a pattern when support arguments
// PATTERNS
// TODO
// * transform to math functions
// * add some randomness
// * add a bunded random recall
$exponential_pattern = array(1,10,30,60,120,350,700,1500,3000,7000,15000,30000,100000); //exp
// $datestorecall = array(1,10,30,60..,61,62..,80..);
$monthly_pattern = array(1,30,60,90,120,150,180,210,240,270,300); //mod30
$weekly_pattern = array(1,7,14,21,28,35,43,50,57,64,71,78,85,93,100,101,107,114,121,128,135,143,150,157,164,171,178,185,193,100); //mod7
$daily_pattern = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30); //mod1
$datestorecall = $exponential_pattern;
$varname='recall';
$pages = ListPages();
# open $feed as read
if (!file_exists($feedfile))
if (!touch($feedfile))
print "Creation of the feed file fails, check write permissions for pmWiki and $feedfile.";
$feed_oldcontent = file_get_contents($feedfile);
$feed_newcontent = '';
# 2 loops can be probably optimized since they are ordered by date
foreach ($pages as $page) {
$recall = PageTextVar($page,$varname);
if ( isset($recall) ) {
$params = explode(" ",$recall);
$patternrecall = $params[1];
$daterecall = $params[0];
switch($patternrecall){
case "daily": $datestorecall = $daily_pattern; break;
case "weekly": $datestorecall = $weekly_pattern; break;
case "monthly": $datestorecall = $monthly_pattern; break;
case "exponentially": $datestorecall = $exponential_pattern; break;
}
foreach ($datestorecall as $day) {
# print $page . " ";
$checkdate = addDate_BehaviorRecall(convertDate_BehaviorRecall($daterecall),$day);
# print $daterecall . " + " . $day . " (" . $checkdate . ") == " . date("d/m/Y");
if ($checkdate==convertDate_BehaviorRecall(date("d/m/Y")))
{
# print " recall time";
# generate GUID
$item_GUID = $page.'_'.$checkdate;
# if not present in file using a regex on the GUID
if (preg_match("/$item_GUID/",$feed_oldcontent) == 0)
{
# generate date
$feed_newitemdate = date(DATE_RSS, time());
# transform line to XML format
$cleaned_page_name = str_replace(".","/",$page);
global $FmtV;
$pagecontent = FmtPageName($FmtV, $page);
$feed_newitem = " <item>
<title>Day $day recall for page $page started at $daterecall</title>
<link>$ScriptUrl/$cleaned_page_name#BehaviorRecallDay$day</link>
<description>This is to improve behaviors you decided yourself were valuable. Also don't forget to improve those instructions to be more and more efficient!$pagecontent</description>
<guid>$item_GUID</guid>
<pubDate>$feed_newitemdate</pubDate>
</item>";
# appending the item
$feed_newcontent .= $feed_newitem;
}
break; #we can't have 2 days at the same time
}
# print "<br/>";
} # check if the next recall day is today
} # check if the next page is tagged
}
# feed should be properly updated
$feed_newdate = date(DATE_RSS, time());
$feed_header = "<?xml version=\"1.0\"?>
<rss version=\"2.0\">
<channel>
<title>BehaviorRecall feed for $WikiTitle .</title>
<link>$ScriptUrl</link>
<description>Receive links as reminded to periodic behaviors you want to transform to habits.</description>
<lastBuildDate>$feed_newdate</lastBuildDate>";
$feed_footer = "
</channel>
</rss>";
# print header
print $feed_header;
# print items
print $feed_oldcontent;
# $feed_newcontent = str_replace(array_keys($EntitiesTable), array_values($EntitiesTable), $feed_newcontent);
print $feed_newcontent;
# print footer
print $feed_footer;
$write_result = file_put_contents($feedfile,$feed_oldcontent.$feed_newcontent);
if (!$write_result)
if (strlen($feed_oldcontent.$feed_newcontent)>0)
print "Creation of the feed file fails, check write permissions for pmWiki and $feedfile.";
else
print "No item to generate, did you correctly tag your pages?";
}
## Since most feeds don't understand html character entities, we
## convert the common ones to their numeric form here.
## Taken from /scripts/feeds.php
SDVA($EntitiesTable, array(
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent"
'&nbsp;' => '&#160;',
'&iexcl;' => '&#161;',
'&cent;' => '&#162;',
'&pound;' => '&#163;',
'&curren;' => '&#164;',
'&yen;' => '&#165;',
'&brvbar;' => '&#166;',
'&sect;' => '&#167;',
'&uml;' => '&#168;',
'&copy;' => '&#169;',
'&ordf;' => '&#170;',
'&laquo;' => '&#171;',
'&not;' => '&#172;',
'&shy;' => '&#173;',
'&reg;' => '&#174;',
'&macr;' => '&#175;',
'&deg;' => '&#176;',
'&plusmn;' => '&#177;',
'&sup2;' => '&#178;',
'&sup3;' => '&#179;',
'&acute;' => '&#180;',
'&micro;' => '&#181;',
'&para;' => '&#182;',
'&middot;' => '&#183;',
'&cedil;' => '&#184;',
'&sup1;' => '&#185;',
'&ordm;' => '&#186;',
'&raquo;' => '&#187;',
'&frac14;' => '&#188;',
'&frac12;' => '&#189;',
'&frac34;' => '&#190;',
'&iquest;' => '&#191;',
'&Agrave;' => '&#192;',
'&Aacute;' => '&#193;',
'&Acirc;' => '&#194;',
'&Atilde;' => '&#195;',
'&Auml;' => '&#196;',
'&Aring;' => '&#197;',
'&AElig;' => '&#198;',
'&Ccedil;' => '&#199;',
'&Egrave;' => '&#200;',
'&Eacute;' => '&#201;',
'&Ecirc;' => '&#202;',
'&Euml;' => '&#203;',
'&Igrave;' => '&#204;',
'&Iacute;' => '&#205;',
'&Icirc;' => '&#206;',
'&Iuml;' => '&#207;',
'&ETH;' => '&#208;',
'&Ntilde;' => '&#209;',
'&Ograve;' => '&#210;',
'&Oacute;' => '&#211;',
'&Ocirc;' => '&#212;',
'&Otilde;' => '&#213;',
'&Ouml;' => '&#214;',
'&times;' => '&#215;',
'&Oslash;' => '&#216;',
'&Ugrave;' => '&#217;',
'&Uacute;' => '&#218;',
'&Ucirc;' => '&#219;',
'&Uuml;' => '&#220;',
'&Yacute;' => '&#221;',
'&THORN;' => '&#222;',
'&szlig;' => '&#223;',
'&agrave;' => '&#224;',
'&aacute;' => '&#225;',
'&acirc;' => '&#226;',
'&atilde;' => '&#227;',
'&auml;' => '&#228;',
'&aring;' => '&#229;',
'&aelig;' => '&#230;',
'&ccedil;' => '&#231;',
'&egrave;' => '&#232;',
'&eacute;' => '&#233;',
'&ecirc;' => '&#234;',
'&euml;' => '&#235;',
'&igrave;' => '&#236;',
'&iacute;' => '&#237;',
'&icirc;' => '&#238;',
'&iuml;' => '&#239;',
'&eth;' => '&#240;',
'&ntilde;' => '&#241;',
'&ograve;' => '&#242;',
'&oacute;' => '&#243;',
'&ocirc;' => '&#244;',
'&otilde;' => '&#245;',
'&ouml;' => '&#246;',
'&divide;' => '&#247;',
'&oslash;' => '&#248;',
'&ugrave;' => '&#249;',
'&uacute;' => '&#250;',
'&ucirc;' => '&#251;',
'&uuml;' => '&#252;',
'&yacute;' => '&#253;',
'&thorn;' => '&#254;',
'&yuml;' => '&#255;',
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent"
'&quot;' => '&#34;',
#'&amp;' => '&#38;#38;',
#'&lt;' => '&#38;#60;',
#'&gt;' => '&#62;',
'&apos;' => '&#39;',
'&OElig;' => '&#338;',
'&oelig;' => '&#339;',
'&Scaron;' => '&#352;',
'&scaron;' => '&#353;',
'&Yuml;' => '&#376;',
'&circ;' => '&#710;',
'&tilde;' => '&#732;',
'&ensp;' => '&#8194;',
'&emsp;' => '&#8195;',
'&thinsp;' => '&#8201;',
'&zwnj;' => '&#8204;',
'&zwj;' => '&#8205;',
'&lrm;' => '&#8206;',
'&rlm;' => '&#8207;',
'&ndash;' => '&#8211;',
'&mdash;' => '&#8212;',
'&lsquo;' => '&#8216;',
'&rsquo;' => '&#8217;',
'&sbquo;' => '&#8218;',
'&ldquo;' => '&#8220;',
'&rdquo;' => '&#8221;',
'&bdquo;' => '&#8222;',
'&dagger;' => '&#8224;',
'&Dagger;' => '&#8225;',
'&permil;' => '&#8240;',
'&lsaquo;' => '&#8249;',
'&rsaquo;' => '&#8250;',
'&euro;' => '&#8364;',
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent"
'&fnof;' => '&#402;',
'&Alpha;' => '&#913;',
'&Beta;' => '&#914;',
'&Gamma;' => '&#915;',
'&Delta;' => '&#916;',
'&Epsilon;' => '&#917;',
'&Zeta;' => '&#918;',
'&Eta;' => '&#919;',
'&Theta;' => '&#920;',
'&Iota;' => '&#921;',
'&Kappa;' => '&#922;',
'&Lambda;' => '&#923;',
'&Mu;' => '&#924;',
'&Nu;' => '&#925;',
'&Xi;' => '&#926;',
'&Omicron;' => '&#927;',
'&Pi;' => '&#928;',
'&Rho;' => '&#929;',
'&Sigma;' => '&#931;',
'&Tau;' => '&#932;',
'&Upsilon;' => '&#933;',
'&Phi;' => '&#934;',
'&Chi;' => '&#935;',
'&Psi;' => '&#936;',
'&Omega;' => '&#937;',
'&alpha;' => '&#945;',
'&beta;' => '&#946;',
'&gamma;' => '&#947;',
'&delta;' => '&#948;',
'&epsilon;' => '&#949;',
'&zeta;' => '&#950;',
'&eta;' => '&#951;',
'&theta;' => '&#952;',
'&iota;' => '&#953;',
'&kappa;' => '&#954;',
'&lambda;' => '&#955;',
'&mu;' => '&#956;',
'&nu;' => '&#957;',
'&xi;' => '&#958;',
'&omicron;' => '&#959;',
'&pi;' => '&#960;',
'&rho;' => '&#961;',
'&sigmaf;' => '&#962;',
'&sigma;' => '&#963;',
'&tau;' => '&#964;',
'&upsilon;' => '&#965;',
'&phi;' => '&#966;',
'&chi;' => '&#967;',
'&psi;' => '&#968;',
'&omega;' => '&#969;',
'&thetasym;' => '&#977;',
'&upsih;' => '&#978;',
'&piv;' => '&#982;',
'&bull;' => '&#8226;',
'&hellip;' => '&#8230;',
'&prime;' => '&#8242;',
'&Prime;' => '&#8243;',
'&oline;' => '&#8254;',
'&frasl;' => '&#8260;',
'&weierp;' => '&#8472;',
'&image;' => '&#8465;',
'&real;' => '&#8476;',
'&trade;' => '&#8482;',
'&alefsym;' => '&#8501;',
'&larr;' => '&#8592;',
'&uarr;' => '&#8593;',
'&rarr;' => '&#8594;',
'&darr;' => '&#8595;',
'&harr;' => '&#8596;',
'&crarr;' => '&#8629;',
'&lArr;' => '&#8656;',
'&uArr;' => '&#8657;',
'&rArr;' => '&#8658;',
'&dArr;' => '&#8659;',
'&hArr;' => '&#8660;',
'&forall;' => '&#8704;',
'&part;' => '&#8706;',
'&exist;' => '&#8707;',
'&empty;' => '&#8709;',
'&nabla;' => '&#8711;',
'&isin;' => '&#8712;',
'&notin;' => '&#8713;',
'&ni;' => '&#8715;',
'&prod;' => '&#8719;',
'&sum;' => '&#8721;',
'&minus;' => '&#8722;',
'&lowast;' => '&#8727;',
'&radic;' => '&#8730;',
'&prop;' => '&#8733;',
'&infin;' => '&#8734;',
'&ang;' => '&#8736;',
'&and;' => '&#8743;',
'&or;' => '&#8744;',
'&cap;' => '&#8745;',
'&cup;' => '&#8746;',
'&int;' => '&#8747;',
'&there4;' => '&#8756;',
'&sim;' => '&#8764;',
'&cong;' => '&#8773;',
'&asymp;' => '&#8776;',
'&ne;' => '&#8800;',
'&equiv;' => '&#8801;',
'&le;' => '&#8804;',
'&ge;' => '&#8805;',
'&sub;' => '&#8834;',
'&sup;' => '&#8835;',
'&nsub;' => '&#8836;',
'&sube;' => '&#8838;',
'&supe;' => '&#8839;',
'&oplus;' => '&#8853;',
'&otimes;' => '&#8855;',
'&perp;' => '&#8869;',
'&sdot;' => '&#8901;',
'&lceil;' => '&#8968;',
'&rceil;' => '&#8969;',
'&lfloor;' => '&#8970;',
'&rfloor;' => '&#8971;',
'&lang;' => '&#9001;',
'&rang;' => '&#9002;',
'&loz;' => '&#9674;',
'&spades;' => '&#9824;',
'&clubs;' => '&#9827;',
'&hearts;' => '&#9829;',
'&diams;' => '&#9830;'));

@ -0,0 +1,75 @@
<?php
# return coeditions for a wholewiki
function Coeditions($groupname){
global $ScriptUrl, $PubDir, $FarmD;
$cache_time = 0; # set to 0 to disable cache, practical for testing
$cache_time = 3600;
$cachefile = "/pub/coedits.txt";
$timewindow = 360; # in seconds
$pagelist = ListPages("/$groupname\./e");
// consider removing structural pages (headers, PmWiki, Site, ...)
// mostly case by default since those remains into wikilib.d unless modified
//unset($pagelist[array_search("$groupname.Template",$pagelist)]);
# cache since its costly
if (!file_exists($FarmD.$cachefile)){
if (!touch($FarmD.$cachefile))
print "Creation of the cache file fails, check write permissions for pmWiki and $cachefile.";
# if cache exist
} else {
# cache has been generated recently
if (( (time() - filemtime($FarmD.$cachefile)) < $cache_time ) && $groupname == "")
#return it
return unserialize(file_get_contents($FarmD.$cachefile));
}
foreach ($pagelist as $pagename){
$page = ReadPage($pagename);
if (!$page) return;
krsort($page); reset($page);
foreach($page as $k=>$v) {
if (!preg_match("/^diff:(\d+):(\d+):?([^:]*)/",$k,$match)) continue;
$diff = intval($match[1]);
$edits[] = array ("diff" => $diff, "name" => $pagename);
$diffs[] = $diff;
$names[] = $pagename;
#automatic index since there might multiple edits with the same diff
}
}
# numeric sort $edits by ascending diff (either regenerate or discard index)
array_multisort($diffs,SORT_ASC,SORT_NUMERIC,$names);
//var_dump($diffs,$names);
$numberofedits = count($diffs);
for ($j=0;$j<$numberofedits;$j++){
if (($diffs[$j+1]-$diffs[$j])<$timewindow){
$target = $names[$j];
$dest = $names[$j+1];
$coedits["$target"]["$dest"]++ ;
# dirty since it's a string, not a proper table but will do for tests
}
}
foreach ($coedits as &$ce){
arsort($ce,SORT_NUMERIC);
//$scoedits[] = $ce;
}
//var_dump($coedits);
# should highlight the highest coedition that is not self
# also remove under a certain threshold, e.g. 1 or rather a sigma of the distribution
# most result are... from the same page
# it could thus be noted then filtered
# also the timewindow gives only short-term result
# a second processing could check over long-term editions between pages
#write cache
if ($groupname == "")
$write_result = file_put_contents($FarmD.$cachefile,serialize($coedits));
return $coedits;
}
?>

@ -0,0 +1,162 @@
<?php
# return the "key pages" of a group
# todo
# http://phpir.com/pagerank-in-php
# http://faculty.ucr.edu/~hanneman/nettext/C10_Centrality.html#Betweenness
# check if isset() really is necessary, seems it was avoided in Coeditions
function GroupKeyPages($groupname,$selectionmechanism=""){
$pages = ListPages("/$groupname\./e");
//note that this could be replaced by proper ListPages call
$pages = CleanPageList($pages,$groupname);
$b = GenerateNetworkFromList($pages);
//var_dump($b);
switch ($selectionmechanism) {
case "NetworkLeverageCentrality":
$keypages = $selectionmechanism($b,0.05); # value threshold
break;
case "NetworkOutgoingIncoming":
$keypages = $selectionmechanism($b,4,5); # outgoing and incoming degree threshold
break;
default:
$keypages = NetworkDegree($b,8); # degree threshold
}
return array_unique($keypages);
}
function GenerateNetworkFromList($pagelist){
foreach ($pagelist as $page) {
$content = ReadPage($page,$since=0);
$links = $content["targets"];
$links_array = explode(",",$links);
foreach ($links_array as $link) {
if (($linkindex = array_search($link,$pagelist)) !== false ){
if (isset($b["$page"]["outgoing"]))
$b["$page"]["outgoing"]++;
else
{ $b["$page"]["outgoing"] = 1; $b["$page"]["name"]=$page; }
if (isset( $b["$link"]["incoming"]))
$b["$link"]["incoming"]++;
else
{ $b["$link"]["incoming"] = 1; $b["$link"]["name"]=$link; }
if (isset($b["$page"]["degree"]))
$b["$page"]["degree"]++;
else
{ $b["$page"]["degree"] = 1; $b["$page"]["name"]=$page; }
if (isset($b["$link"]["degree"]))
$b["$link"]["degree"]++;
else
{ $b["$link"]["degree"] = 1; $b["$link"]["name"]=$link; }
$b["$page"]["neighboors"][] = $link;
$b["$link"]["neighboors"][] = $page;
}
}
}
return $b;
}
function CleanPageList($pagelist,$groupname){
// rather arbitrary, not necessarily a good choice
unset($pagelist[array_search("$groupname.$groupname",$pagelist)]);
unset($pagelist[array_search("$groupname.Template",$pagelist)]);
unset($pagelist[array_search("$groupname.GroupHeader",$pagelist)]);
unset($pagelist[array_search("$groupname.GroupFooter",$pagelist)]);
return $pagelist;
}
function NetworkOutgoingIncoming($b,$IncomingThreshold=0,$OutgoingThreshold=0){
$keypages = array(); //done to avoid returning notthing if the theshold is too high
foreach ($b as $bs){
if (isset($bs["incoming"]))
if ($bs["incoming"] > $IncomingThreshold )
$keypages[] = $bs["name"];
if (isset($bs["outgoing"]))
if ($bs["outgoing"] > $OutgoingThreshold )
$keypages[] = $bs["name"];
}
return $keypages;
}
function NetworkDegree($b, $DegreeThreshold=0){
$keypages = array(); //done to avoid returning notthing if the theshold is too high
foreach ($b as $bs){
if (isset($bs["degree"]))
if ($bs["degree"] > $DegreeThreshold )
$keypages[] = $bs["name"];
}
return $keypages;
}
function NetworkLeverageCentrality($b,$Threshold=0){
$keypages = array(); //done to avoid returning notthing if the theshold is too high
foreach ($b as $bs){
if (isset($bs["neighboors"])){
$bs["leveragecentrality"] = 0;
$sum = 0; $avg=0;
foreach($bs["neighboors"] as $neighboor){
$sum += ($bs["degree"] - $b["$neighboor"]["degree"]) / ($bs["degree"] + $b["$neighboor"]["degree"]);
$avg += $b["$neighboor"]["degree"];
}
if ($bs["degree"] > 0){
$avg = $avg / $bs["degree"];
if ($avg > 0){
$bs["leveragecentrality"] = ($sum/$avg) / $bs["degree"];
}
}
if ($bs["leveragecentrality"] > $Threshold )
$keypages[] = $bs["name"];
}
}
return $keypages;
}
function GroupDegreeDistribution($groupname){
$pages = ListPages("/$groupname\./e");
//note that this could be replaced by proper ListPages call
$pages = CleanPageList($pages,$groupname);
$b = GenerateNetworkFromList($pages);
$distribution = array_fill(1,10,0);
// has no effect
foreach ($b as $node){
$degree = $node["degree"];
if (isset($distribution[$degree]))
$distribution[$degree]++;
else
$distribution[$degree]=1;
$sumdeg += $node["degree"];
$sumin += $node["incoming"];
$sumout += $node["outgoing"];
}
$avgdeg = $sumdeg / count($b);
$avgin = $sumin / count($b);
$avgout = $sumout / count($b);
/*
print "avgdeg = $avgdeg; ";
print "avgin = $avgin; ";
print "avgout = $avgout; ";
strangely equal, probably a mistake there
*/
ksort($distribution);
/* fails to get the proper last key
end($distribution);
$last_key = key($distribution);
print $last_key;
for ($i=1;i<$last_key;$i++)
if (!(isset($distribution[$i])))
$distribution[$i]=0;
*/
return array_unique($distribution);
}
?>

@ -0,0 +1,50 @@
<?php
# give a visual representation of pages and group
#
# action for the whole wiki (equivalent to group="") done through AllPages fake group
# add the GroupKeyPages function as a parameter
$RecipeInfo['GroupStats']['Version'] = '2011-08-06';
$HandleActions['GroupStats'] = 'GroupStats'; # if url contains action=myaction call HandleMyAction timely
$HandleAuth['GroupStats'] = 'read'; # authorization level $auth for HandleMyAction
function GroupStats($pagename, $auth){
list($group,$page) = explode(".",$pagename);
$distmax = 15;
if ($group == "AllPages"){
// equivalent to getting ALL pages
$group = "";
$distmax = 50;
}
$dist= GroupDegreeDistribution($group);
for($i=1;$i<$distmax;$i++){
if (isset($dist[$i]))
$distribution .= $dist[$i].",";
else
$distribution .= "0,";
}
$max = max($dist);
$upperbound = $dist[($distmax/5)];
$img = "http://sparklines.bitworking.info/spark.cgi?type=impulse"
."&d=$distribution&height=100"
."&limits=0,$max"
."&upper=$upperbound&above-color=red&below-color=gray&width=15&.png";
$selectingalgo = "NetworkDegree";
# can also be NetworkOutgoingIncoming or NetworkLeverageCentrality or NetworkDegree
# threshold are set later on
$keypages = var_export(GroupKeyPages($group, $selectingalgo),true);
$coeditions = var_export(Coeditions($group),true);
# could be improvied by coloring
# link to self
# links that do not exist explicitely
print "<h1>Group statistics for $group</h1>"
."<hr/><h2>Degree distribution</h2>(from d(1) to d(max), d()=0 excluded, max(d())=2, avg(d())~=4):</br>"
.$distribution."<br><img src=\"$img\" /><br>"
."<hr/><h2><a name=\"Key pages\"></a>Keypages using $selectingalgo</h2><pre>".$keypages."</pre>"
."<hr/><h2><a name=\"Coeditions\"></a>Coedition</h2><pre>".$coeditions."</pre>";
}
?>

@ -0,0 +1,386 @@
<?php if (!defined('PmWiki')) exit();
/*
inspired by PageFeed by Daniel Roesler (diafygi)
conversation array imported from it
*/
## Recipe version information
$RecipeInfo['Memorization']['Version'] = '2010-04-02';
## Add action for pagefeed
SDV($HandleActions['memorization'], 'Memorization');
# from http://www.pmwiki.org/wiki/PmWiki/Functions
function FeedText($pagename, &$page, $tag) {
$text = RetrieveAuthSection("ReadingNotes.GroupHeader","");
$content = MarkupToHTML($pagename, $text);
$text = RetrieveAuthSection($pagename, '##Chapter2');
$content .= MarkupToHTML($pagename, $text);
return "<$tag><![CDATA[$content]]></$tag>";
}
function addDate($date,$day)//add days
{
$sum = strtotime(date("Y-m-d", strtotime("$date")) . " +$day days");
$dateTo=date('Y-m-d',$sum);
return $dateTo;
}
function convertdate($date) {
return preg_replace("/(\d+)\/(\d+)\/(\d+)/",'$3-$2-$1',$date);
}
## Create feed from page history
function Memorization($pagename, $auth = 'read') {
global $FarmD, $WikiTitle, $ScriptUrl;
$feedfile = $FarmD."/pub/memorizationfeed.xml"; #change to a pattern when support arguments
$datestorecall = array(1,10,30,60,120,350,700,1500,3000,7000,15000,30000,100000);
// $datestorecall = array(1,10,30,60..,61,62..,80..);
$varname='startrecall';
$pages = ListPages();
# open $feed as read
if (!file_exists($feedfile))
if (!touch($feedfile))
print "Creation of the feed file fails, check write permissions for pmWiki and $feedfile.";
$feed_oldcontent = file_get_contents($feedfile);
$feed_newcontent = '';
# 2 loops can be probably optimized since they are ordered by date
foreach ($pages as $page) {
$daterecall = PageTextVar($page,$varname);
if ( isset($daterecall) ) {
foreach ($datestorecall as $day) {
# print $page . " ";
$checkdate = addDate(convertdate($daterecall),$day);
# print $daterecall . " + " . $day . " (" . $checkdate . ") == " . date("d/m/Y");
if ($checkdate==convertdate(date("d/m/Y")))
{
# print " recall time";
# generate GUID
$item_GUID = $page.'_'.$checkdate;
# if not present in file using a regex on the GUID
if (preg_match("/$item_GUID/",$feed_oldcontent) == 0)
{
# generate date
$feed_newitemdate = date(DATE_RSS, time());
# transform line to XML format
$cleaned_page_name = str_replace(".","/",$page);
// function FeedText($pagename, &$page, $tag) {
//"manually" add the cover by simulating the GroupHeadre (read page ISBN + if exist display image)
$feed_newitem = " <item>
<title>Day $day recall for page $page started at $daterecall</title>
<link>$ScriptUrl/$cleaned_page_name#MemorizationDay$day</link>"
.FeedText($page,$page,"description").
"<guid>$item_GUID</guid>
<pubDate>$feed_newitemdate</pubDate>
</item>";
# bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )
# appending the item
$feed_newcontent .= $feed_newitem;
}
break; #we can't have 2 days at the same time
}
# print "<br/>";
} # check if the next recall day is today
} # check if the next page is tagged
}
# feed should be properly updated
$feed_newdate = date(DATE_RSS, time());
$feed_header = "<?xml version=\"1.0\"?>
<rss version=\"2.0\">
<channel>
<title>Memorization feed for $WikiTitle .</title>
<link>$ScriptUrl</link>
<description>Receive links to the page you tagged in order to have optimal memorization.</description>
<generator>Generated by http://fabien.benetou.fr/Wiki/MemoryRecipe for PmWiki</generator>
<lastBuildDate>$feed_newdate</lastBuildDate>";
$feed_footer = "
</channel>
</rss>";
# print header
print $feed_header;
# print items
print $feed_oldcontent;
# $feed_newcontent = str_replace(array_keys($EntitiesTable), array_values($EntitiesTable), $feed_newcontent);
print $feed_newcontent;
# print footer
print $feed_footer;
$write_result = file_put_contents($feedfile,$feed_oldcontent.$feed_newcontent);
if (!$write_result)
if (strlen($feed_oldcontent.$feed_newcontent)>0)
print "Creation of the feed file fails, check write permissions for pmWiki and $feedfile.";
else
print "No item to generate, did you correctly tag your pages?";
}
## Since most feeds don't understand html character entities, we
## convert the common ones to their numeric form here.
## Taken from /scripts/feeds.php
SDVA($EntitiesTable, array(
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent"
'&nbsp;' => '&#160;',
'&iexcl;' => '&#161;',
'&cent;' => '&#162;',
'&pound;' => '&#163;',
'&curren;' => '&#164;',
'&yen;' => '&#165;',
'&brvbar;' => '&#166;',
'&sect;' => '&#167;',
'&uml;' => '&#168;',
'&copy;' => '&#169;',
'&ordf;' => '&#170;',
'&laquo;' => '&#171;',
'&not;' => '&#172;',
'&shy;' => '&#173;',
'&reg;' => '&#174;',
'&macr;' => '&#175;',
'&deg;' => '&#176;',
'&plusmn;' => '&#177;',
'&sup2;' => '&#178;',
'&sup3;' => '&#179;',
'&acute;' => '&#180;',
'&micro;' => '&#181;',
'&para;' => '&#182;',
'&middot;' => '&#183;',
'&cedil;' => '&#184;',
'&sup1;' => '&#185;',
'&ordm;' => '&#186;',
'&raquo;' => '&#187;',
'&frac14;' => '&#188;',
'&frac12;' => '&#189;',
'&frac34;' => '&#190;',
'&iquest;' => '&#191;',
'&Agrave;' => '&#192;',
'&Aacute;' => '&#193;',
'&Acirc;' => '&#194;',
'&Atilde;' => '&#195;',
'&Auml;' => '&#196;',
'&Aring;' => '&#197;',
'&AElig;' => '&#198;',
'&Ccedil;' => '&#199;',
'&Egrave;' => '&#200;',
'&Eacute;' => '&#201;',
'&Ecirc;' => '&#202;',
'&Euml;' => '&#203;',
'&Igrave;' => '&#204;',
'&Iacute;' => '&#205;',
'&Icirc;' => '&#206;',
'&Iuml;' => '&#207;',
'&ETH;' => '&#208;',
'&Ntilde;' => '&#209;',
'&Ograve;' => '&#210;',
'&Oacute;' => '&#211;',
'&Ocirc;' => '&#212;',
'&Otilde;' => '&#213;',
'&Ouml;' => '&#214;',
'&times;' => '&#215;',
'&Oslash;' => '&#216;',
'&Ugrave;' => '&#217;',
'&Uacute;' => '&#218;',
'&Ucirc;' => '&#219;',
'&Uuml;' => '&#220;',
'&Yacute;' => '&#221;',
'&THORN;' => '&#222;',
'&szlig;' => '&#223;',
'&agrave;' => '&#224;',
'&aacute;' => '&#225;',
'&acirc;' => '&#226;',
'&atilde;' => '&#227;',
'&auml;' => '&#228;',
'&aring;' => '&#229;',
'&aelig;' => '&#230;',
'&ccedil;' => '&#231;',
'&egrave;' => '&#232;',
'&eacute;' => '&#233;',
'&ecirc;' => '&#234;',
'&euml;' => '&#235;',
'&igrave;' => '&#236;',
'&iacute;' => '&#237;',
'&icirc;' => '&#238;',
'&iuml;' => '&#239;',
'&eth;' => '&#240;',
'&ntilde;' => '&#241;',
'&ograve;' => '&#242;',
'&oacute;' => '&#243;',
'&ocirc;' => '&#244;',
'&otilde;' => '&#245;',
'&ouml;' => '&#246;',
'&divide;' => '&#247;',
'&oslash;' => '&#248;',
'&ugrave;' => '&#249;',
'&uacute;' => '&#250;',
'&ucirc;' => '&#251;',
'&uuml;' => '&#252;',
'&yacute;' => '&#253;',
'&thorn;' => '&#254;',
'&yuml;' => '&#255;',
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent"
'&quot;' => '&#34;',
#'&amp;' => '&#38;#38;',
#'&lt;' => '&#38;#60;',
#'&gt;' => '&#62;',
'&apos;' => '&#39;',
'&OElig;' => '&#338;',
'&oelig;' => '&#339;',
'&Scaron;' => '&#352;',
'&scaron;' => '&#353;',
'&Yuml;' => '&#376;',
'&circ;' => '&#710;',
'&tilde;' => '&#732;',
'&ensp;' => '&#8194;',
'&emsp;' => '&#8195;',
'&thinsp;' => '&#8201;',
'&zwnj;' => '&#8204;',
'&zwj;' => '&#8205;',
'&lrm;' => '&#8206;',
'&rlm;' => '&#8207;',
'&ndash;' => '&#8211;',
'&mdash;' => '&#8212;',
'&lsquo;' => '&#8216;',
'&rsquo;' => '&#8217;',
'&sbquo;' => '&#8218;',
'&ldquo;' => '&#8220;',
'&rdquo;' => '&#8221;',
'&bdquo;' => '&#8222;',
'&dagger;' => '&#8224;',
'&Dagger;' => '&#8225;',
'&permil;' => '&#8240;',
'&lsaquo;' => '&#8249;',
'&rsaquo;' => '&#8250;',
'&euro;' => '&#8364;',
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent"
'&fnof;' => '&#402;',
'&Alpha;' => '&#913;',
'&Beta;' => '&#914;',
'&Gamma;' => '&#915;',
'&Delta;' => '&#916;',
'&Epsilon;' => '&#917;',
'&Zeta;' => '&#918;',
'&Eta;' => '&#919;',
'&Theta;' => '&#920;',
'&Iota;' => '&#921;',
'&Kappa;' => '&#922;',
'&Lambda;' => '&#923;',
'&Mu;' => '&#924;',
'&Nu;' => '&#925;',
'&Xi;' => '&#926;',
'&Omicron;' => '&#927;',
'&Pi;' => '&#928;',
'&Rho;' => '&#929;',
'&Sigma;' => '&#931;',
'&Tau;' => '&#932;',
'&Upsilon;' => '&#933;',
'&Phi;' => '&#934;',
'&Chi;' => '&#935;',
'&Psi;' => '&#936;',
'&Omega;' => '&#937;',
'&alpha;' => '&#945;',
'&beta;' => '&#946;',
'&gamma;' => '&#947;',
'&delta;' => '&#948;',
'&epsilon;' => '&#949;',
'&zeta;' => '&#950;',
'&eta;' => '&#951;',
'&theta;' => '&#952;',
'&iota;' => '&#953;',
'&kappa;' => '&#954;',
'&lambda;' => '&#955;',
'&mu;' => '&#956;',
'&nu;' => '&#957;',
'&xi;' => '&#958;',
'&omicron;' => '&#959;',
'&pi;' => '&#960;',
'&rho;' => '&#961;',
'&sigmaf;' => '&#962;',
'&sigma;' => '&#963;',
'&tau;' => '&#964;',
'&upsilon;' => '&#965;',
'&phi;' => '&#966;',
'&chi;' => '&#967;',
'&psi;' => '&#968;',
'&omega;' => '&#969;',
'&thetasym;' => '&#977;',
'&upsih;' => '&#978;',
'&piv;' => '&#982;',
'&bull;' => '&#8226;',
'&hellip;' => '&#8230;',
'&prime;' => '&#8242;',
'&Prime;' => '&#8243;',
'&oline;' => '&#8254;',
'&frasl;' => '&#8260;',
'&weierp;' => '&#8472;',
'&image;' => '&#8465;',
'&real;' => '&#8476;',
'&trade;' => '&#8482;',
'&alefsym;' => '&#8501;',
'&larr;' => '&#8592;',
'&uarr;' => '&#8593;',
'&rarr;' => '&#8594;',
'&darr;' => '&#8595;',
'&harr;' => '&#8596;',
'&crarr;' => '&#8629;',
'&lArr;' => '&#8656;',
'&uArr;' => '&#8657;',
'&rArr;' => '&#8658;',
'&dArr;' => '&#8659;',
'&hArr;' => '&#8660;',
'&forall;' => '&#8704;',
'&part;' => '&#8706;',
'&exist;' => '&#8707;',
'&empty;' => '&#8709;',
'&nabla;' => '&#8711;',
'&isin;' => '&#8712;',
'&notin;' => '&#8713;',
'&ni;' => '&#8715;',
'&prod;' => '&#8719;',
'&sum;' => '&#8721;',
'&minus;' => '&#8722;',
'&lowast;' => '&#8727;',
'&radic;' => '&#8730;',
'&prop;' => '&#8733;',
'&infin;' => '&#8734;',
'&ang;' => '&#8736;',
'&and;' => '&#8743;',
'&or;' => '&#8744;',
'&cap;' => '&#8745;',
'&cup;' => '&#8746;',
'&int;' => '&#8747;',
'&there4;' => '&#8756;',
'&sim;' => '&#8764;',
'&cong;' => '&#8773;',
'&asymp;' => '&#8776;',
'&ne;' => '&#8800;',
'&equiv;' => '&#8801;',
'&le;' => '&#8804;',
'&ge;' => '&#8805;',
'&sub;' => '&#8834;',
'&sup;' => '&#8835;',
'&nsub;' => '&#8836;',
'&sube;' => '&#8838;',
'&supe;' => '&#8839;',
'&oplus;' => '&#8853;',
'&otimes;' => '&#8855;',
'&perp;' => '&#8869;',
'&sdot;' => '&#8901;',
'&lceil;' => '&#8968;',
'&rceil;' => '&#8969;',
'&lfloor;' => '&#8970;',
'&rfloor;' => '&#8971;',
'&lang;' => '&#9001;',
'&rang;' => '&#9002;',
'&loz;' => '&#9674;',
'&spades;' => '&#9824;',
'&clubs;' => '&#9827;',
'&hearts;' => '&#9829;',
'&diams;' => '&#9830;'));

@ -0,0 +1,218 @@
<?php
// PIM functions (for PmWiki)
// consider adding other related scripts here too (e.g. MemoryRecipe, Recalls, GroupStats, Coeditions, ...)
// http://fabien.benetou.fr/pub/graphformatexporter.php.txt
// http://fabien.benetou.fr/pub/memorization.php.txt
// note that the order is important though
// e.g. currently MemoryRecipe is loaded after thus can't be called here
// add to http://fabien.benetou.fr/repository/
// it would be particularly useful to refactor each properly
// especially since they share variables (e.g. first edit) but also some have better function
// e.g. caching in Coeditions
// change ProcessingJS generation by first producing JSON
// via http://www.php.net/manual/en/function.json-encode.php
// cf http://fabien.benetou.fr/Tools/Processing and http://fabien.benetou.fr/Tools/JavaScript
// this might be even faster on most computers since JS engines are improving
//handle implicit linking
/*
cf http://fabien.benetou.fr/MemoryRecalls/ImprovingPIM#ImplicitLinking
*/
function ImplicitLinking(){
return "list of pages generated on the fly";
}
//$AutoCreate['/\\.GroupStats$/'] = array( 'ctime' => $Now, 'text' => ImplicitLinking());
//$AutoCreate['/^Categora\\./'] = array('ctime' => $Now);
//doesn't work, AutoCreate present in pmwiki.php and example too
// category works though
// TODO try making it global $AutoCreate;
//display working status
// see http://fabien.benetou.fr/Tools/Greasemonkey#VirtualBlinders
Markup("currenttask", "directives", "/\(:currenttask:\)/", GetCurrentTask());
function GetCurrentTask(){
$currenttask = trim(file_get_contents("/home/utopiah/web/benetou.fr/fabien/pub/currenttask"));
if ($currenttask == "")
return "(either available or asleep, Im usually on CET)";
return "[[CognitiveEnvironments/".$currenttask."]]";
}
Markup("timetable", "fulltext", "/\(:timetable:\)/",
"\n||border=1\n||!Time ||!Action ||\n"
.preg_replace("/.* (\d+) (\d+).* \/(.*)/","||$1:$2||$3||",file_get_contents("/home/utopiah/.irssi/cron.save"))
."");
//load a dedicated edition page for the admin (shouldn't be hard coded but I dont use Auth)
//global $GLOBALS;
if ($GLOBALS['action'] == 'edit' && ( $GLOBALS['Author'] == 'Fabien' || $GLOBALS['Author'] == 'Utopiah' ) )
{
//TODO fails since moved in cookbook directory, thus added back there
global $SkinDir,$pagename;
LoadPageTemplate($pagename, "$SkinDir/edit.tmpl");
}
//display editions through an horizontal line
/*
fomally done via GnuPlot, cf http://fabien.benetou.fr/Wiki/Visualization#timeline
http://www.scholarpedia.org/article/Spike-response_model is probably too complicated for the small resolution
yet provide interesting non-linear properties
*/
function DisplayVisualEdits($pagename){
global $ScriptUrl, $PubDir, $FarmD;
$processingpath = '/pub/libraries/processing.js';
$processingfile = "/pub/visualization/edits_per_page/$pagename.pjs";
$processinglib = "<script src=\"$processingpath\" type=\"text/javascript\"></script>";
$first_edit = 1212192000;
$now = time();
// draw the timeline from the first edit to now()
// get the list of edits of the current page
// "get inspired" by PrintDiff() in scripts/pagerev.php
$canvaswidth = 600-2*10;
$canvasheight = 10;
$block_width = 4;
$block_height = 8;
$page = ReadPage($pagename);
if (!$page) return;
krsort($page); reset($page);
// newest first
// for each edit
$canvas = "
void setup()
{
size($canvaswidth, $canvasheight);
PFont font;
font = loadFont(\"FFScala-Bold-12.vlw\");
textFont(font);
}
void mouseMoved() {
checkButtons();
}
void mouseDragged() {
checkButtons();
}
void draw()
{
background(251);
fill(0,0,255,20);
noStroke();
";
$mousePressed = "void mousePressed() {";
$destination_link = "$ScriptUrl/".strtr($pagename,".","/")."?action=diff#diff";
$mousePressed .= "\t\tif (lastHovered>0) { link(\"$destination_link\"+lastHovered); }\n";
$checkButtons = "void checkButtons() {";
print $processinglib.'<canvas data-src="'.$processingfile.'" width="'.$canvaswidth.'" height="'.$canvasheight.'"></canvas>';
// set to false to de-activate cache (practical for tests)
$newest_diff = true;
//$newest_diff = false;
//$first_diff = true;
foreach($page as $k=>$v) {
if (!preg_match("/^diff:(\d+):(\d+):?([^:]*)/",$k,$match)) continue;
$diff = $match[1];
$diffclass = $match[3];
if ($diffclass=='minor')
{ $canvas .= "\t\tfill(0,255,0,20);\n"; }
else
{ $canvas .= "\t\tfill(0,0,255,20);\n"; }
//if ($first_diff)
// { $canvas .= "\t\tfill(255,0,0,20);\n"; $first_diff = false;}
$buttonname = "over".$diff."Button";
//$bools .= "boolean $buttonname = false;\n";
if (file_exists($FarmD.$processingfile) && $newest_diff)
if ( filemtime($FarmD.$processingfile) > $diff)
return;
$newest_diff = false;
// add a sightly transparent tick rectangle with its Unix timestamp link to the diff page
// the mouse over a certain edit should change its color
// see http://processingjs.org/learning/basic/embeddedlinks
// or clicablerects.js via Pomax on :mozilla2/#processing.js (14/05/2011 ~11pm)
$x = round ( ($canvaswidth - $block_width) * ( (($now - $first_edit)-($now-$diff)) / ($now - $first_edit)));
$y = 1;
$checkButtons .= "\t\tif ( mouseX > $x && mouseX < $x+$block_width) lastHovered = $diff; \n";
// if (mouseY > $y && mouseY < $y+$block_height) not really required
// others should be set to false else one always jump to the olded diff mouved over
$canvas .= "\t\trect($x,$y,$block_width,$block_height);\n";
}
$canvas .= "\t\tstroke(0,155);\n";
$canvas .= "\t\tfill(0,0,255,80);\n";
$canvas .= "\t\ttext(\"Edits:\",2,10 );\n";
$canvas .= "\t\tfill(0,0,255,40);\n";
for ($year=2009;$year<2012;$year++){ //each year until now
$unixyear = mktime(0,0,0,1,1,$year);
$x = round ( ($canvaswidth - $block_width) * ( (($now - $first_edit)-($now-$unixyear)) / ($now - $first_edit)));
$y = 0;
$canvas .= "line($x,$y,$x,$y+$block_height+2); text(\"$year\",$x+2,$y+10 );\n";
}
$canvas = $bools . $canvas ."}" . $mousePressed ."}" .$checkButtons . "}";
// load ProcessinJS
$write_result = file_put_contents($FarmD.$processingfile,$canvas);
// print resulting canvas
$older_gnuplot_version = "<div><center><img src=\"/pub/visualization/edits_per_page/{$pagename}.png\" alt=\"/pub/visualization/edits_per_page/{$pagename}.png\"/></br>(<a href=\"$ScriptUrl/Wiki/Visualization#timeline\">visualization details</a>).</center></div><hr />";
}
//display images with transparancy invertionnaly proportional to last time of update
// http://fabien.benetou.fr/MemoryRecalls/ImprovingPIM#VisualDecayOfInformation
function DisplayDecay($pagename){
/*
consider
adding threshold
not keeping it linear (e.g. log)
but still constantly inscreasing between 0 and 1
use a factor when matches (e.g. regex changing $impeding_factor or $first_edit)
regex would match groupname (e.g. "Person." with fast decay) or pagename or both (e.g. "Math" with slow decay)
yellowish background, looking like old paper
...rest got deleted by a dumb rm...
*/
global $ScriptUrl;
$first_edit = 1212192000;
$now = time();
//load page
$page = ReadPage($pagename);
if (!$page) return;
$last_edit = $page["time"];
//get last edit
$destination_link = "$ScriptUrl/".strtr($pagename,".","/")."?action=edit";
//use the previous equation adding 1 - ()
$opacity = round ( 1 - ( (($now - $first_edit)-($now-$last_edit)) / ($now - $first_edit)) , 2 );
$opacitymsg = "opacity=$opacity";
if ($opacity > 0.8)
$opacitymsg = "<font color=\"red\">".$opacitymsg."</font>";
//if user if admin
if ( $GLOBALS['Author'] == 'Fabien' || $GLOBALS['Author'] == 'Utopiah' ) {
//for 1 to a multiplier of value
for ($i=0;$i<$opacity*10;$i++){
// display another visual problem with a link back to improvingwiki#visualdecay
print "<div style=\"opacity:$opacity;position:absolute;top:".rand(60,800)."px;left:".rand(100,500)."px;\"><a href=\"$destination_link\">"
.decbin(rand(0,10000))."</a></div>";
}
// add a good practice msg
print "<div style=\"opacity:$opacity;position:absolute;top:10px;left:450px;width:300px;background-color:gray;\">
$opacitymsg edits should be done to check if
the informamtion presented is still relevant,
links are working,
opinion expressed still correct, etc.
</div>";
}
//print img with opacity + warning message
print "<div style=\"opacity:$opacity;\"><a name=\"Decay\"></a>If you can read this text ($opacitymsg) if means the page has not been edited for a long time. Consequently the information it holds might be deprecated or no longer represent the opinion of this author.</div>";
}

@ -0,0 +1,109 @@
<?php
## give a visual representation of pages and group
$RecipeInfo['WikiBrainMapping']['Version'] = '2011-05-15';
Markup('WikiBrainMapping', 'directives', '/\\(:WikiBrainMapping:\\)/e', Keep(WikiBrainMapping()));
function WikiBrainMapping(){
$sourcepagename = $_SERVER["REQUEST_URI"];
// apply changes done to graphprocessing.php to insure proper URI format
$sourcepagename = preg_replace("/(.*)\?.*/","$1",$sourcepagename);
$sourcename = preg_replace("/.*[\.\/](.*)/","$1",$sourcepagename);
$sourcegroup = preg_replace("/\/(.*)[\/\.].*/","$1",$sourcepagename);
if ($sourcegroup == "/"){
$sourcegroup = "Main";
# consider instead filling the pages array with
## groups names
## "neighboors" wikis from InterWiki page
# list page, remove pagenames, sort|uniq ... then what? maybe whole different process
}
global $FarmD, $WikiTitle, $ScriptUrl;
$processingpath = '/pub/libraries/processing.js';
$processingfile = "/pub/visualization/wikibrainmapping.pjs";
$processinglib = "<script src=\"$processingpath\" type=\"text/javascript\"></script>";
# eventually modify to use a dedicated folder
# generate a file per page
if (!file_exists($FarmD.$processingfile))
if (!touch($FarmD.$processingfile))
print "Creation of the processing file fails, check write permissions for pmWiki and $processingfile.";
# cached version (to comment during tests)
#if ( (time() - filemtime($FarmD.$processingfile)) < 3600 ) return $processinglib.'<canvas data-src="'.$processingfile.'" width="'.$canvaswidth.'" height="'.$canvasheight.'"></canvas>';
$canvaswidth=500;
$canvasheight=300;
$groupname = $sourcegroup;
$pages = ListPages("/$groupname\./e");
$pages = MatchPageNames($pages,array('-*.*RecentChanges,-*.GroupFooter,-*.GroupHeader'));
$pagesnum = count($pages);
$processingsetupcode = "
PShape s;
void setup(){
frameRate(15);
size($canvaswidth,$canvasheight);
strokeWeight(2);
PFont font;
font = loadFont(\"FFScala-32.vlw\");
textFont(font);
sright = loadShape(\"/pub/illustrations/flat_brain_right.svg\");
sleft = loadShape(\"/pub/illustrations/flat_brain_left.svg\");
smooth();
";
$processingdrawcode .= "
void draw(){
background(255);
";
$processingdrawcode .= "shape(sright,300, 400);";
$processingdrawcode .= "shape(sleft,200, 400);";
$processingdrawcode .= "fill(0,0,255,255);\n";
$processingdrawcode .= "text(\"flattened left hemisphere\",300,10);\n;";
$processingdrawcode .= "text(\"flattened right hemisphere\",100,10);\n;";
$target_area["x"] = 150;
$target_area["y"] = 100;
$target_area["width"] = 50;
$target_area["height"] = 60;
//replace with actual list of pages
for ($pagen=0;$pagen<10;$pagen++){
$x = rand($target_area["x"],$target_area["x"]+$target_area["width"]);
$y = rand($target_area["y"],$target_area["y"]+$target_area["height"]);
//draw cercle in the area
$radius = 3;
$processingdrawcode .= "fill(255,0,0,100);ellipse($x,$y,$radius,$radius);\n";
//draw diagonal line of edits
$linelength=10;
$processingdrawcode .= "strokeWeight(1); line($x,$y,$x+$linelength,$y-$linelength);\n";
//replace with actual list of edits
$maxdiff = rand(0,10);
for ($diff=0;$diff<$maxdiff;$diff++){
//draw points on the line of edits with smaller stroke weight
$diff_pos = rand(0,$linelength);
$processingdrawcode .= "strokeWeight(2); point($x+$diff_pos,$y-$diff_pos);\n";
}
}
$processingdrawcode .= "fill(255,0,0,255);\n";
$processingdrawcode .= "text(\"Note that currently points are randomly generated\\nand randomly positionned on a designated area.\\nNo mapping has been done between function and position.\\nGyri and sulci are also not represented.\",10,200);\n;";
$processingsetupcode .= " }";
$processingdrawcode .= " }";
$result = $processinglib.'<canvas data-src="'.$processingfile.'" width="'.$canvaswidth.'" height="'.$canvasheight.'"></canvas>';
$write_result = file_put_contents($FarmD.$processingfile,$processingsetupcode.$processingdrawcode);
if (!$write_result)
if (strlen($processingcode)>0)
print "Creation of the feed file fails, check write permissions for pmWiki and $processingfile.";
else
print "No code to generate, did you correctly generate your Processing code?";
// ----------------------- return the processed result -----------------------
return $result;
}
?>
Loading…
Cancel
Save