diff --git a/cookbook/behavior_recall.php b/cookbook/behavior_recall.php
new file mode 100644
index 0000000..df08ae2
--- /dev/null
+++ b/cookbook/behavior_recall.php
@@ -0,0 +1,394 @@
+
+
Day $day recall for page $page started at $daterecall
+ $ScriptUrl/$cleaned_page_name#BehaviorRecallDay$day
+ 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
+ $item_GUID
+ $feed_newitemdate
+ ";
+ # appending the item
+ $feed_newcontent .= $feed_newitem;
+ }
+ break; #we can't have 2 days at the same time
+ }
+ # print " ";
+ } # 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 = "
+
+
+ BehaviorRecall feed for $WikiTitle .
+ $ScriptUrl
+ Receive links as reminded to periodic behaviors you want to transform to habits.
+ $feed_newdate ";
+
+ $feed_footer = "
+
+ ";
+
+
+ # 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"
+ ' ' => ' ',
+ '¡' => '¡',
+ '¢' => '¢',
+ '£' => '£',
+ '¤' => '¤',
+ '¥' => '¥',
+ '¦' => '¦',
+ '§' => '§',
+ '¨' => '¨',
+ '©' => '©',
+ 'ª' => 'ª',
+ '«' => '«',
+ '¬' => '¬',
+ '' => '',
+ '®' => '®',
+ '¯' => '¯',
+ '°' => '°',
+ '±' => '±',
+ '²' => '²',
+ '³' => '³',
+ '´' => '´',
+ 'µ' => 'µ',
+ '¶' => '¶',
+ '·' => '·',
+ '¸' => '¸',
+ '¹' => '¹',
+ 'º' => 'º',
+ '»' => '»',
+ '¼' => '¼',
+ '½' => '½',
+ '¾' => '¾',
+ '¿' => '¿',
+ 'À' => 'À',
+ 'Á' => 'Á',
+ 'Â' => 'Â',
+ 'Ã' => 'Ã',
+ 'Ä' => 'Ä',
+ 'Å' => 'Å',
+ 'Æ' => 'Æ',
+ 'Ç' => 'Ç',
+ 'È' => 'È',
+ 'É' => 'É',
+ 'Ê' => 'Ê',
+ 'Ë' => 'Ë',
+ 'Ì' => 'Ì',
+ 'Í' => 'Í',
+ 'Î' => 'Î',
+ 'Ï' => 'Ï',
+ 'Ð' => 'Ð',
+ 'Ñ' => 'Ñ',
+ 'Ò' => 'Ò',
+ 'Ó' => 'Ó',
+ 'Ô' => 'Ô',
+ 'Õ' => 'Õ',
+ 'Ö' => 'Ö',
+ '×' => '×',
+ 'Ø' => 'Ø',
+ 'Ù' => 'Ù',
+ 'Ú' => 'Ú',
+ 'Û' => 'Û',
+ 'Ü' => 'Ü',
+ 'Ý' => 'Ý',
+ 'Þ' => 'Þ',
+ 'ß' => 'ß',
+ 'à' => 'à',
+ 'á' => 'á',
+ 'â' => 'â',
+ 'ã' => 'ã',
+ 'ä' => 'ä',
+ 'å' => 'å',
+ 'æ' => 'æ',
+ 'ç' => 'ç',
+ 'è' => 'è',
+ 'é' => 'é',
+ 'ê' => 'ê',
+ 'ë' => 'ë',
+ 'ì' => 'ì',
+ 'í' => 'í',
+ 'î' => 'î',
+ 'ï' => 'ï',
+ 'ð' => 'ð',
+ 'ñ' => 'ñ',
+ 'ò' => 'ò',
+ 'ó' => 'ó',
+ 'ô' => 'ô',
+ 'õ' => 'õ',
+ 'ö' => 'ö',
+ '÷' => '÷',
+ 'ø' => 'ø',
+ 'ù' => 'ù',
+ 'ú' => 'ú',
+ 'û' => 'û',
+ 'ü' => 'ü',
+ 'ý' => 'ý',
+ 'þ' => 'þ',
+ 'ÿ' => 'ÿ',
+ # entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent"
+ '"' => '"',
+ #'&' => '&',
+ #'<' => '<',
+ #'>' => '>',
+ ''' => ''',
+ 'Œ' => 'Œ',
+ 'œ' => 'œ',
+ 'Š' => 'Š',
+ 'š' => 'š',
+ 'Ÿ' => 'Ÿ',
+ 'ˆ' => 'ˆ',
+ '˜' => '˜',
+ ' ' => ' ',
+ ' ' => ' ',
+ ' ' => ' ',
+ '' => '',
+ '' => '',
+ '' => '',
+ '' => '',
+ '–' => '–',
+ '—' => '—',
+ '‘' => '‘',
+ '’' => '’',
+ '‚' => '‚',
+ '“' => '“',
+ '”' => '”',
+ '„' => '„',
+ '†' => '†',
+ '‡' => '‡',
+ '‰' => '‰',
+ '‹' => '‹',
+ '›' => '›',
+ '€' => '€',
+ # entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent"
+ 'ƒ' => 'ƒ',
+ 'Α' => 'Α',
+ 'Β' => 'Β',
+ 'Γ' => 'Γ',
+ 'Δ' => 'Δ',
+ 'Ε' => 'Ε',
+ 'Ζ' => 'Ζ',
+ 'Η' => 'Η',
+ 'Θ' => 'Θ',
+ 'Ι' => 'Ι',
+ 'Κ' => 'Κ',
+ 'Λ' => 'Λ',
+ 'Μ' => 'Μ',
+ 'Ν' => 'Ν',
+ 'Ξ' => 'Ξ',
+ 'Ο' => 'Ο',
+ 'Π' => 'Π',
+ 'Ρ' => 'Ρ',
+ 'Σ' => 'Σ',
+ 'Τ' => 'Τ',
+ 'Υ' => 'Υ',
+ 'Φ' => 'Φ',
+ 'Χ' => 'Χ',
+ 'Ψ' => 'Ψ',
+ 'Ω' => 'Ω',
+ 'α' => 'α',
+ 'β' => 'β',
+ 'γ' => 'γ',
+ 'δ' => 'δ',
+ 'ε' => 'ε',
+ 'ζ' => 'ζ',
+ 'η' => 'η',
+ 'θ' => 'θ',
+ 'ι' => 'ι',
+ 'κ' => 'κ',
+ 'λ' => 'λ',
+ 'μ' => 'μ',
+ 'ν' => 'ν',
+ 'ξ' => 'ξ',
+ 'ο' => 'ο',
+ 'π' => 'π',
+ 'ρ' => 'ρ',
+ 'ς' => 'ς',
+ 'σ' => 'σ',
+ 'τ' => 'τ',
+ 'υ' => 'υ',
+ 'φ' => 'φ',
+ 'χ' => 'χ',
+ 'ψ' => 'ψ',
+ 'ω' => 'ω',
+ 'ϑ' => 'ϑ',
+ 'ϒ' => 'ϒ',
+ 'ϖ' => 'ϖ',
+ '•' => '•',
+ '…' => '…',
+ '′' => '′',
+ '″' => '″',
+ '‾' => '‾',
+ '⁄' => '⁄',
+ '℘' => '℘',
+ 'ℑ' => 'ℑ',
+ 'ℜ' => 'ℜ',
+ '™' => '™',
+ 'ℵ' => 'ℵ',
+ '←' => '←',
+ '↑' => '↑',
+ '→' => '→',
+ '↓' => '↓',
+ '↔' => '↔',
+ '↵' => '↵',
+ '⇐' => '⇐',
+ '⇑' => '⇑',
+ '⇒' => '⇒',
+ '⇓' => '⇓',
+ '⇔' => '⇔',
+ '∀' => '∀',
+ '∂' => '∂',
+ '∃' => '∃',
+ '∅' => '∅',
+ '∇' => '∇',
+ '∈' => '∈',
+ '∉' => '∉',
+ '∋' => '∋',
+ '∏' => '∏',
+ '∑' => '∑',
+ '−' => '−',
+ '∗' => '∗',
+ '√' => '√',
+ '∝' => '∝',
+ '∞' => '∞',
+ '∠' => '∠',
+ '∧' => '∧',
+ '∨' => '∨',
+ '∩' => '∩',
+ '∪' => '∪',
+ '∫' => '∫',
+ '∴' => '∴',
+ '∼' => '∼',
+ '≅' => '≅',
+ '≈' => '≈',
+ '≠' => '≠',
+ '≡' => '≡',
+ '≤' => '≤',
+ '≥' => '≥',
+ '⊂' => '⊂',
+ '⊃' => '⊃',
+ '⊄' => '⊄',
+ '⊆' => '⊆',
+ '⊇' => '⊇',
+ '⊕' => '⊕',
+ '⊗' => '⊗',
+ '⊥' => '⊥',
+ '⋅' => '⋅',
+ '⌈' => '⌈',
+ '⌉' => '⌉',
+ '⌊' => '⌊',
+ '⌋' => '⌋',
+ '〈' => '〈',
+ '〉' => '〉',
+ '◊' => '◊',
+ '♠' => '♠',
+ '♣' => '♣',
+ '♥' => '♥',
+ '♦' => '♦'));
diff --git a/cookbook/coeditions.php b/cookbook/coeditions.php
new file mode 100644
index 0000000..312275f
--- /dev/null
+++ b/cookbook/coeditions.php
@@ -0,0 +1,75 @@
+$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;
+}
+
+?>
diff --git a/cookbook/groupkeypages.php b/cookbook/groupkeypages.php
new file mode 100644
index 0000000..1a67f88
--- /dev/null
+++ b/cookbook/groupkeypages.php
@@ -0,0 +1,162 @@
+ $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);
+}
+
+?>
diff --git a/cookbook/groupstats.php b/cookbook/groupstats.php
new file mode 100644
index 0000000..c588d61
--- /dev/null
+++ b/cookbook/groupstats.php
@@ -0,0 +1,50 @@
+Group statistics for $group"
+ ."Degree distribution (from d(1) to d(max), d()=0 excluded, max(d())=2, avg(d())~=4):"
+ .$distribution." "
+ ." Keypages using $selectingalgo".$keypages." "
+ ." Coedition".$coeditions." ";
+}
+
+
+?>
diff --git a/cookbook/memorization.php b/cookbook/memorization.php
new file mode 100644
index 0000000..d8652bd
--- /dev/null
+++ b/cookbook/memorization.php
@@ -0,0 +1,386 @@
+$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 = " -
+
Day $day recall for page $page started at $daterecall
+ $ScriptUrl/$cleaned_page_name#MemorizationDay$day"
+ .FeedText($page,$page,"description").
+ "$item_GUID
+ $feed_newitemdate
+ ";
+ # 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 " ";
+ } # 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 = "
+
+
+ Memorization feed for $WikiTitle .
+ $ScriptUrl
+ Receive links to the page you tagged in order to have optimal memorization.
+ Generated by http://fabien.benetou.fr/Wiki/MemoryRecipe for PmWiki
+ $feed_newdate ";
+
+ $feed_footer = "
+
+ ";
+
+
+ # 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"
+ ' ' => ' ',
+ '¡' => '¡',
+ '¢' => '¢',
+ '£' => '£',
+ '¤' => '¤',
+ '¥' => '¥',
+ '¦' => '¦',
+ '§' => '§',
+ '¨' => '¨',
+ '©' => '©',
+ 'ª' => 'ª',
+ '«' => '«',
+ '¬' => '¬',
+ '' => '',
+ '®' => '®',
+ '¯' => '¯',
+ '°' => '°',
+ '±' => '±',
+ '²' => '²',
+ '³' => '³',
+ '´' => '´',
+ 'µ' => 'µ',
+ '¶' => '¶',
+ '·' => '·',
+ '¸' => '¸',
+ '¹' => '¹',
+ 'º' => 'º',
+ '»' => '»',
+ '¼' => '¼',
+ '½' => '½',
+ '¾' => '¾',
+ '¿' => '¿',
+ 'À' => 'À',
+ 'Á' => 'Á',
+ 'Â' => 'Â',
+ 'Ã' => 'Ã',
+ 'Ä' => 'Ä',
+ 'Å' => 'Å',
+ 'Æ' => 'Æ',
+ 'Ç' => 'Ç',
+ 'È' => 'È',
+ 'É' => 'É',
+ 'Ê' => 'Ê',
+ 'Ë' => 'Ë',
+ 'Ì' => 'Ì',
+ 'Í' => 'Í',
+ 'Î' => 'Î',
+ 'Ï' => 'Ï',
+ 'Ð' => 'Ð',
+ 'Ñ' => 'Ñ',
+ 'Ò' => 'Ò',
+ 'Ó' => 'Ó',
+ 'Ô' => 'Ô',
+ 'Õ' => 'Õ',
+ 'Ö' => 'Ö',
+ '×' => '×',
+ 'Ø' => 'Ø',
+ 'Ù' => 'Ù',
+ 'Ú' => 'Ú',
+ 'Û' => 'Û',
+ 'Ü' => 'Ü',
+ 'Ý' => 'Ý',
+ 'Þ' => 'Þ',
+ 'ß' => 'ß',
+ 'à' => 'à',
+ 'á' => 'á',
+ 'â' => 'â',
+ 'ã' => 'ã',
+ 'ä' => 'ä',
+ 'å' => 'å',
+ 'æ' => 'æ',
+ 'ç' => 'ç',
+ 'è' => 'è',
+ 'é' => 'é',
+ 'ê' => 'ê',
+ 'ë' => 'ë',
+ 'ì' => 'ì',
+ 'í' => 'í',
+ 'î' => 'î',
+ 'ï' => 'ï',
+ 'ð' => 'ð',
+ 'ñ' => 'ñ',
+ 'ò' => 'ò',
+ 'ó' => 'ó',
+ 'ô' => 'ô',
+ 'õ' => 'õ',
+ 'ö' => 'ö',
+ '÷' => '÷',
+ 'ø' => 'ø',
+ 'ù' => 'ù',
+ 'ú' => 'ú',
+ 'û' => 'û',
+ 'ü' => 'ü',
+ 'ý' => 'ý',
+ 'þ' => 'þ',
+ 'ÿ' => 'ÿ',
+ # entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent"
+ '"' => '"',
+ #'&' => '&',
+ #'<' => '<',
+ #'>' => '>',
+ ''' => ''',
+ 'Œ' => 'Œ',
+ 'œ' => 'œ',
+ 'Š' => 'Š',
+ 'š' => 'š',
+ 'Ÿ' => 'Ÿ',
+ 'ˆ' => 'ˆ',
+ '˜' => '˜',
+ ' ' => ' ',
+ ' ' => ' ',
+ ' ' => ' ',
+ '' => '',
+ '' => '',
+ '' => '',
+ '' => '',
+ '–' => '–',
+ '—' => '—',
+ '‘' => '‘',
+ '’' => '’',
+ '‚' => '‚',
+ '“' => '“',
+ '”' => '”',
+ '„' => '„',
+ '†' => '†',
+ '‡' => '‡',
+ '‰' => '‰',
+ '‹' => '‹',
+ '›' => '›',
+ '€' => '€',
+ # entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent"
+ 'ƒ' => 'ƒ',
+ 'Α' => 'Α',
+ 'Β' => 'Β',
+ 'Γ' => 'Γ',
+ 'Δ' => 'Δ',
+ 'Ε' => 'Ε',
+ 'Ζ' => 'Ζ',
+ 'Η' => 'Η',
+ 'Θ' => 'Θ',
+ 'Ι' => 'Ι',
+ 'Κ' => 'Κ',
+ 'Λ' => 'Λ',
+ 'Μ' => 'Μ',
+ 'Ν' => 'Ν',
+ 'Ξ' => 'Ξ',
+ 'Ο' => 'Ο',
+ 'Π' => 'Π',
+ 'Ρ' => 'Ρ',
+ 'Σ' => 'Σ',
+ 'Τ' => 'Τ',
+ 'Υ' => 'Υ',
+ 'Φ' => 'Φ',
+ 'Χ' => 'Χ',
+ 'Ψ' => 'Ψ',
+ 'Ω' => 'Ω',
+ 'α' => 'α',
+ 'β' => 'β',
+ 'γ' => 'γ',
+ 'δ' => 'δ',
+ 'ε' => 'ε',
+ 'ζ' => 'ζ',
+ 'η' => 'η',
+ 'θ' => 'θ',
+ 'ι' => 'ι',
+ 'κ' => 'κ',
+ 'λ' => 'λ',
+ 'μ' => 'μ',
+ 'ν' => 'ν',
+ 'ξ' => 'ξ',
+ 'ο' => 'ο',
+ 'π' => 'π',
+ 'ρ' => 'ρ',
+ 'ς' => 'ς',
+ 'σ' => 'σ',
+ 'τ' => 'τ',
+ 'υ' => 'υ',
+ 'φ' => 'φ',
+ 'χ' => 'χ',
+ 'ψ' => 'ψ',
+ 'ω' => 'ω',
+ 'ϑ' => 'ϑ',
+ 'ϒ' => 'ϒ',
+ 'ϖ' => 'ϖ',
+ '•' => '•',
+ '…' => '…',
+ '′' => '′',
+ '″' => '″',
+ '‾' => '‾',
+ '⁄' => '⁄',
+ '℘' => '℘',
+ 'ℑ' => 'ℑ',
+ 'ℜ' => 'ℜ',
+ '™' => '™',
+ 'ℵ' => 'ℵ',
+ '←' => '←',
+ '↑' => '↑',
+ '→' => '→',
+ '↓' => '↓',
+ '↔' => '↔',
+ '↵' => '↵',
+ '⇐' => '⇐',
+ '⇑' => '⇑',
+ '⇒' => '⇒',
+ '⇓' => '⇓',
+ '⇔' => '⇔',
+ '∀' => '∀',
+ '∂' => '∂',
+ '∃' => '∃',
+ '∅' => '∅',
+ '∇' => '∇',
+ '∈' => '∈',
+ '∉' => '∉',
+ '∋' => '∋',
+ '∏' => '∏',
+ '∑' => '∑',
+ '−' => '−',
+ '∗' => '∗',
+ '√' => '√',
+ '∝' => '∝',
+ '∞' => '∞',
+ '∠' => '∠',
+ '∧' => '∧',
+ '∨' => '∨',
+ '∩' => '∩',
+ '∪' => '∪',
+ '∫' => '∫',
+ '∴' => '∴',
+ '∼' => '∼',
+ '≅' => '≅',
+ '≈' => '≈',
+ '≠' => '≠',
+ '≡' => '≡',
+ '≤' => '≤',
+ '≥' => '≥',
+ '⊂' => '⊂',
+ '⊃' => '⊃',
+ '⊄' => '⊄',
+ '⊆' => '⊆',
+ '⊇' => '⊇',
+ '⊕' => '⊕',
+ '⊗' => '⊗',
+ '⊥' => '⊥',
+ '⋅' => '⋅',
+ '⌈' => '⌈',
+ '⌉' => '⌉',
+ '⌊' => '⌊',
+ '⌋' => '⌋',
+ '〈' => '〈',
+ '〉' => '〉',
+ '◊' => '◊',
+ '♠' => '♠',
+ '♣' => '♣',
+ '♥' => '♥',
+ '♦' => '♦'));
diff --git a/cookbook/pim_functions.php b/cookbook/pim_functions.php
new file mode 100644
index 0000000..296afa5
--- /dev/null
+++ b/cookbook/pim_functions.php
@@ -0,0 +1,218 @@
+ $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 = "";
+ $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.' ';
+ // 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 = " ";
+}
+
+
+//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 = "".$opacitymsg." ";
+
+ //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 "";
+ }
+ // add a good practice msg
+ print "
+ $opacitymsg edits should be done to check if
+ the informamtion presented is still relevant,
+ links are working,
+ opinion expressed still correct, etc.
+
";
+ }
+
+
+ //print img with opacity + warning message
+
+ print "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.
";
+
+}
diff --git a/cookbook/wikibrainmapping.php b/cookbook/wikibrainmapping.php
new file mode 100644
index 0000000..54ed913
--- /dev/null
+++ b/cookbook/wikibrainmapping.php
@@ -0,0 +1,109 @@
+";
+
+ # 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.' ';
+
+ $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.' ';
+
+ $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;
+}
+
+?>