wok diff wikiss/stuff/plugins/wkp_Calc.php @ rev 15573

wikiss: add Calc plugin
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Nov 28 19:25:13 2013 +0000 (2013-11-28)
parents
children 019e831466f7
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/wikiss/stuff/plugins/wkp_Calc.php	Thu Nov 28 19:25:13 2013 +0000
     1.3 @@ -0,0 +1,173 @@
     1.4 +<?php # coding: utf-8
     1.5 +
     1.6 +class Calc
     1.7 +{
     1.8 +   public $description = "Feuille de calcul au format CSV";
     1.9 +   
    1.10 +   var $lines = 0, $rows = 0, $cnt = 0, $gotcalc = 0, $line = array();
    1.11 +   var $newCONTENT;
    1.12 +   function showcalc()
    1.13 +   {
    1.14 +      if ($this->lines > 1 && $this->rows > 1) {
    1.15 +         $id = "C".(100+$this->cnt++); 
    1.16 +         $this->newCONTENT .= "<noscript><a href=\"http://www.enable-javascript.com/\" target=\"_blank\">Enable javascript to see the spreadsheet ".$id."</a></noscript>\n";
    1.17 +         $this->newCONTENT .= "<table id=\"".$id."\" class=\"tablecalc\"></table>\n";
    1.18 +         $this->newCONTENT .= "<script type=\"text/javascript\">\n";
    1.19 +         $this->newCONTENT .= "<!--\n";
    1.20 +         $this->newCONTENT .= "buildCalc(\"".$id."\",".$this->lines.",".$this->rows.");\n";
    1.21 +         for ($i = 1; $i <= $this->lines; $i++) {
    1.22 +            $this->line[$i] = preg_replace("/&lt;/","<",$this->line[$i]);
    1.23 +            for ($tmp = explode(";",$this->line[$i]), $j = 0; $j < count($tmp) -1; $j++) {
    1.24 +               if ($tmp[$j] == "") continue;
    1.25 +               $tmp[$j] = preg_replace("/\"/","\\\\\"",$tmp[$j]);
    1.26 +               $s = "setCell(document.getElementById(\"".$id;
    1.27 +               $this->newCONTENT .= $s.chr(ord('A')+$j).$i."\"), \"".$tmp[$j]."\")\n";
    1.28 +            }
    1.29 +         }
    1.30 +         $this->newCONTENT .= "//-->\n";
    1.31 +         $this->newCONTENT .= "</script>\n";
    1.32 +      }
    1.33 +      else for ($i = 1; $i <= $this->lines; $i++)
    1.34 +         $this->newCONTENT .= $this->line[$i]."\n";
    1.35 +      $this->rows = $this->lines = $this->gotcalc = 0;
    1.36 +   }
    1.37 +
    1.38 +   function formatEnd()
    1.39 +   {
    1.40 +      global $CONTENT;
    1.41 +      $headdone = $gotcalc = $showtail = $this->lines = 0;
    1.42 +      $this->newCONTENT = "";
    1.43 +      $CONTENT = preg_replace("/<br \/>/","<br />\n",$CONTENT);
    1.44 +      foreach (explode("\n", $CONTENT) as $current) {
    1.45 +      	 if ($current == "") continue;
    1.46 +         if (preg_match("/;<br \/>$/", $current)) {
    1.47 +            $gotcalc = 1;
    1.48 +            if (!$headdone) {
    1.49 +               $headdone = 1;
    1.50 +               $showtail = 1;
    1.51 +               $this->newCONTENT .= <<<EOT
    1.52 +<!-- Based on http://jsfiddle.net/ondras/hYfN3/ by Ondřej Žára -->
    1.53 +<script type="text/javascript">
    1.54 +<!--
    1.55 +function csv(id,rows,cols) {
    1.56 +    var data = "";
    1.57 +    for (var i=1; i<=rows; i++) {
    1.58 +	for (var j=1; j<=cols; j++) {
    1.59 +            var letter = String.fromCharCode("A".charCodeAt(0)+j-1);
    1.60 +	    data += document.getElementById(id+letter+i).title+';';
    1.61 +	}
    1.62 +	data += "\\n";
    1.63 +    }
    1.64 +    alert(data);
    1.65 +}
    1.66 +
    1.67 +var DATA={};
    1.68 +function buildCalc(id, rows, cols) {
    1.69 +    DATA[id] = {};
    1.70 +    var maths = [ "abs", "acos", "asin", "atan", "atan2", "ceil", "cos", "exp",
    1.71 +		  "floor", "log", "max", "min", "pow", "random", "round", "sin",
    1.72 +		  "tan", "sqrt", "PI", "E" ];
    1.73 +    for (var i=0; v = maths[i]; i++)
    1.74 +	eval("DATA[id]."+v+" = DATA[id]."+v.toUpperCase()+" = Math."+v);
    1.75 +    DATA[id].rand = DATA[id].RAND = Math.random;
    1.76 +    DATA[id].ln   = DATA[id].LN   = Math.log;
    1.77 +    DATA[id].log10= DATA[id].LOG10= function(n){return Math.log(n)/Math.LN10;};
    1.78 +    DATA[id].log2 = DATA[id].LOG2 = function(n){return Math.log(n)/Math.LN2;};
    1.79 +    DATA[id].fact = DATA[id].FACT = 
    1.80 +	function(n){var x=1;while(n>1)x*=n--;return x;};
    1.81 +    DATA[id].fib  = DATA[id].FIB  = 
    1.82 +	function(n){var c=0,p=1;while(n-->0){var x=c;c+=p;p=x};return c;};
    1.83 +    for (var i=0; i<=rows; i++) {
    1.84 +        var row = document.getElementById(id).insertRow(-1);
    1.85 +        for (var j=0; j<=cols && j<=26; j++) {
    1.86 +            var letter = String.fromCharCode("A".charCodeAt(0)+j-1);
    1.87 +	    var cell = row.insertCell(-1);
    1.88 +	    if (i&&j) {
    1.89 +		cell.className = "cellcalc";
    1.90 +		cell.innerHTML = "<input id='"+ id+letter+i +"' class='inputcalc'/>";
    1.91 +	    }
    1.92 +	    else {
    1.93 +		cell.className = "bordercalc";
    1.94 +		cell.title = "Show CSV";
    1.95 +		cell.onclick = function(){csv(id,rows,cols);};
    1.96 +		cell.innerHTML = (i||j) ? i||letter : "&radic;";
    1.97 +	    }
    1.98 +        }
    1.99 +    }
   1.100 +}
   1.101 +
   1.102 +function getWidth(s)
   1.103 +{
   1.104 +	var e = document.getElementById("widthcalc");
   1.105 +	e.innerHTML = s+" :";
   1.106 +	return (e.offsetWidth < 80 || s.charAt(0) == "=") ? 80 : e.offsetWidth;
   1.107 +}
   1.108 +
   1.109 +function setCell(e, v)
   1.110 +{
   1.111 +    e.style.width = getWidth(v)+"px";
   1.112 +    e.style.textAlign = 
   1.113 +	(isNaN(parseFloat(v)) && v.charAt(0) != "=") ? "left" : "right";
   1.114 +    e.title = v;
   1.115 +}
   1.116 +//-->
   1.117 +</script>
   1.118 +<span id="widthcalc" class="cellcalc" style="visibility:hidden;"></span>
   1.119 +EOT;
   1.120 +            }
   1.121 +            $this->line[++$this->lines] = $current;
   1.122 +            $current = preg_replace("/&lt;/","<",$current);
   1.123 +            $i = count(explode(";", $current))-1;
   1.124 +            if ($this->lines == 1) $this->rows = $i;
   1.125 +            if ($i != $this->rows) $this->rows = -1;
   1.126 +         }
   1.127 +         else {
   1.128 +            if ($gotcalc) $this->showcalc();
   1.129 +            $this->newCONTENT .= $current."\n";
   1.130 +         }
   1.131 +      }
   1.132 +      if ($gotcalc) $this->showcalc();
   1.133 +      if ($showtail) {
   1.134 +         $this->newCONTENT .= <<<EOT
   1.135 +<script type="text/javascript">
   1.136 +<!--
   1.137 +var INPUTS=[].slice.call(document.getElementsByClassName("inputcalc"));
   1.138 +INPUTS.forEach(function(elm) {
   1.139 +    elm.onfocus = function(e) {
   1.140 +        e.target.value = e.target.title || "";
   1.141 +    };
   1.142 +    elm.onblur = function(e) {
   1.143 +	setCell(e.target, e.target.value);
   1.144 +        computeAll();
   1.145 +    };
   1.146 +    var calcid = elm.id.substring(0,4), cellid = elm.id.substring(4);
   1.147 +    var getter = function() {
   1.148 +        var value = elm.title || "";
   1.149 +        if (value.charAt(0) == "=")
   1.150 +		with (DATA[calcid]) return eval(value.substring(1));
   1.151 +        else return isNaN(parseFloat(value)) ? value : parseFloat(value);
   1.152 +    };
   1.153 +    Object.defineProperty(DATA[calcid], cellid, {get:getter});
   1.154 +    Object.defineProperty(DATA[calcid], cellid.toLowerCase(), {get:getter});
   1.155 +});
   1.156 +(window.computeAll = function() {
   1.157 +    INPUTS.forEach(function(elm) {
   1.158 +	var calcid = elm.id.substring(0,4), cellid = elm.id.substring(4);
   1.159 +	try { elm.value = DATA[calcid][cellid]; } catch(e) {} });
   1.160 +})();
   1.161 +//-->
   1.162 +</script>
   1.163 +EOT;
   1.164 +      }
   1.165 +      $CONTENT = $this->newCONTENT;
   1.166 +   }
   1.167 +
   1.168 +   function template()
   1.169 +   {
   1.170 +      global $html;
   1.171 +      $html = preg_replace("/<\/head>/",
   1.172 +      "\t<style type=\"text/css\"> @import \"plugins/wkp_Calc.css\"; </style>\n</head>",
   1.173 +      $html);
   1.174 +   }
   1.175 +}
   1.176 +?>