wok annotate wikiss/stuff/plugins/wkp_Calc.php @ rev 25037

Up glza (0.11.4)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sat May 21 21:38:29 2022 +0000 (2022-05-21)
parents 136be2b3c085
children
rev   line source
pascal@15573 1 <?php # coding: utf-8
pascal@15573 2
pascal@15573 3 class Calc
pascal@15573 4 {
pascal@15573 5 public $description = "Feuille de calcul au format CSV";
pascal@15573 6
pascal@15573 7 var $lines = 0, $rows = 0, $cnt = 0, $gotcalc = 0, $line = array();
pascal@15573 8 var $newCONTENT;
pascal@15573 9 function showcalc()
pascal@15573 10 {
pascal@15573 11 if ($this->lines > 1 && $this->rows > 1) {
pascal@15573 12 $id = "C".(100+$this->cnt++);
pascal@15573 13 $this->newCONTENT .= "<noscript><a href=\"http://www.enable-javascript.com/\" target=\"_blank\">Enable javascript to see the spreadsheet ".$id."</a></noscript>\n";
pascal@15573 14 $this->newCONTENT .= "<table id=\"".$id."\" class=\"tablecalc\"></table>\n";
pascal@15573 15 $this->newCONTENT .= "<script type=\"text/javascript\">\n";
pascal@15573 16 $this->newCONTENT .= "<!--\n";
pascal@15573 17 $this->newCONTENT .= "buildCalc(\"".$id."\",".$this->lines.",".$this->rows.");\n";
pascal@15573 18 for ($i = 1; $i <= $this->lines; $i++) {
pascal@15573 19 $this->line[$i] = preg_replace("/&lt;/","<",$this->line[$i]);
pascal@15573 20 for ($tmp = explode(";",$this->line[$i]), $j = 0; $j < count($tmp) -1; $j++) {
pascal@15573 21 if ($tmp[$j] == "") continue;
pascal@15573 22 $tmp[$j] = preg_replace("/\"/","\\\\\"",$tmp[$j]);
pascal@15573 23 $s = "setCell(document.getElementById(\"".$id;
pascal@15573 24 $this->newCONTENT .= $s.chr(ord('A')+$j).$i."\"), \"".$tmp[$j]."\")\n";
pascal@15573 25 }
pascal@15573 26 }
pascal@15573 27 $this->newCONTENT .= "//-->\n";
pascal@15573 28 $this->newCONTENT .= "</script>\n";
pascal@15573 29 }
pascal@15573 30 else for ($i = 1; $i <= $this->lines; $i++)
pascal@15573 31 $this->newCONTENT .= $this->line[$i]."\n";
pascal@15573 32 $this->rows = $this->lines = $this->gotcalc = 0;
pascal@15573 33 }
pascal@15573 34
pascal@15573 35 function formatEnd()
pascal@15573 36 {
pascal@15573 37 global $CONTENT;
pascal@15573 38 $headdone = $gotcalc = $showtail = $this->lines = 0;
pascal@15573 39 $this->newCONTENT = "";
pascal@15573 40 $CONTENT = preg_replace("/<br \/>/","<br />\n",$CONTENT);
pascal@15573 41 foreach (explode("\n", $CONTENT) as $current) {
pascal@15573 42 if ($current == "") continue;
pascal@15573 43 if (preg_match("/;<br \/>$/", $current)) {
pascal@15573 44 $gotcalc = 1;
pascal@15573 45 if (!$headdone) {
pascal@15573 46 $headdone = 1;
pascal@15573 47 $showtail = 1;
pascal@15573 48 $this->newCONTENT .= <<<EOT
pascal@15573 49 <!-- Based on http://jsfiddle.net/ondras/hYfN3/ by Ondřej Žára -->
pascal@15573 50 <script type="text/javascript">
pascal@15573 51 <!--
pascal@15573 52 function csv(id,rows,cols) {
pascal@15573 53 var data = "";
pascal@15573 54 for (var i=1; i<=rows; i++) {
pascal@15573 55 for (var j=1; j<=cols; j++) {
pascal@15573 56 var letter = String.fromCharCode("A".charCodeAt(0)+j-1);
pascal@15573 57 data += document.getElementById(id+letter+i).title+';';
pascal@15573 58 }
pascal@15573 59 data += "\\n";
pascal@15573 60 }
pascal@15573 61 alert(data);
pascal@15573 62 }
pascal@15573 63
pascal@17794 64 function cnt(from,to) {
pascal@17794 65 return (to.charCodeAt(0) - from.charCodeAt(0) + 1) *
pascal@17794 66 (parseInt(to.substring(1)) - parseInt(from.substring(1)) + 1)
pascal@17794 67 }
pascal@17794 68
pascal@17794 69 function zone(id,from,to,init,func) {
pascal@17794 70 var result=init
pascal@17794 71 for (var l=from.charCodeAt(0);;l++) {
pascal@17794 72 for (var n=parseInt(from.substring(1));
pascal@17794 73 n <= parseInt(to.substring(1));n++) {
pascal@17794 74 var e=document.getElementById(id+String.fromCharCode(l)+n)
pascal@17794 75 result=func(result,parseFloat(e.value))
pascal@17794 76 }
pascal@17794 77 if (l == to.charCodeAt(0)) break
pascal@17794 78 }
pascal@17794 79 return result;
pascal@17794 80 }
pascal@17794 81
pascal@15573 82 var DATA={};
pascal@15573 83 function buildCalc(id, rows, cols) {
pascal@15573 84 DATA[id] = {};
pascal@15573 85 var maths = [ "abs", "acos", "asin", "atan", "atan2", "ceil", "cos", "exp",
pascal@15573 86 "floor", "log", "max", "min", "pow", "random", "round", "sin",
pascal@15573 87 "tan", "sqrt", "PI", "E" ];
pascal@15573 88 for (var i=0; v = maths[i]; i++)
pascal@15573 89 eval("DATA[id]."+v+" = DATA[id]."+v.toUpperCase()+" = Math."+v);
pascal@15573 90 DATA[id].rand = DATA[id].RAND = Math.random;
pascal@15573 91 DATA[id].ln = DATA[id].LN = Math.log;
pascal@15573 92 DATA[id].log10= DATA[id].LOG10= function(n){return Math.log(n)/Math.LN10;};
pascal@15573 93 DATA[id].log2 = DATA[id].LOG2 = function(n){return Math.log(n)/Math.LN2;};
pascal@15573 94 DATA[id].fact = DATA[id].FACT =
pascal@15573 95 function(n){var x=1;while(n>1)x*=n--;return x;};
pascal@15573 96 DATA[id].fib = DATA[id].FIB =
pascal@15573 97 function(n){var c=0,p=1;while(n-->0){var x=c;c+=p;p=x};return c;};
pascal@17794 98 DATA[id].sum = DATA[id].SUM =
pascal@17794 99 function(a,b){return zone(id,a,b,0,function(a,b){return a+b});};
pascal@17794 100 DATA[id].min = DATA[id].MIN =
pascal@17794 101 function(a,b){return zone(id,a,b,Number.MAX_VALUE,Math.min);};
pascal@17794 102 DATA[id].max = DATA[id].MAX =
pascal@17794 103 function(a,b){return zone(id,a,b,Number.MIN_VALUE,Math.max);};
pascal@17794 104 DATA[id].cnt = DATA[id].CNT = cnt
pascal@15573 105 for (var i=0; i<=rows; i++) {
pascal@15573 106 var row = document.getElementById(id).insertRow(-1);
pascal@15573 107 for (var j=0; j<=cols && j<=26; j++) {
pascal@15573 108 var letter = String.fromCharCode("A".charCodeAt(0)+j-1);
pascal@15573 109 var cell = row.insertCell(-1);
pascal@15573 110 if (i&&j) {
pascal@15573 111 cell.className = "cellcalc";
pascal@15573 112 cell.innerHTML = "<input id='"+ id+letter+i +"' class='inputcalc'/>";
pascal@15573 113 }
pascal@15573 114 else {
pascal@15573 115 cell.className = "bordercalc";
pascal@15573 116 cell.title = "Show CSV";
pascal@15573 117 cell.onclick = function(){csv(id,rows,cols);};
pascal@15573 118 cell.innerHTML = (i||j) ? i||letter : "&radic;";
pascal@15573 119 }
pascal@15573 120 }
pascal@15573 121 }
pascal@15573 122 }
pascal@15573 123
pascal@15573 124 function getWidth(s)
pascal@15573 125 {
pascal@15573 126 var e = document.getElementById("widthcalc");
pascal@17794 127 e.innerHTML = s;
pascal@15573 128 return (e.offsetWidth < 80 || s.charAt(0) == "=") ? 80 : e.offsetWidth;
pascal@15573 129 }
pascal@15573 130
pascal@15573 131 function setCell(e, v)
pascal@15573 132 {
pascal@15573 133 e.style.width = getWidth(v)+"px";
pascal@15573 134 e.style.textAlign =
pascal@15573 135 (isNaN(parseFloat(v)) && v.charAt(0) != "=") ? "left" : "right";
pascal@15573 136 e.title = v;
pascal@15573 137 }
pascal@15573 138 //-->
pascal@15573 139 </script>
pascal@15573 140 <span id="widthcalc" class="cellcalc" style="visibility:hidden;"></span>
pascal@15573 141 EOT;
pascal@15573 142 }
pascal@15573 143 $this->line[++$this->lines] = $current;
pascal@15573 144 $current = preg_replace("/&lt;/","<",$current);
pascal@15573 145 $i = count(explode(";", $current))-1;
pascal@15573 146 if ($this->lines == 1) $this->rows = $i;
pascal@15573 147 if ($i != $this->rows) $this->rows = -1;
pascal@15573 148 }
pascal@15573 149 else {
pascal@15573 150 if ($gotcalc) $this->showcalc();
pascal@15573 151 $this->newCONTENT .= $current."\n";
pascal@15573 152 }
pascal@15573 153 }
pascal@15573 154 if ($gotcalc) $this->showcalc();
pascal@15573 155 if ($showtail) {
pascal@15573 156 $this->newCONTENT .= <<<EOT
pascal@15573 157 <script type="text/javascript">
pascal@15573 158 <!--
pascal@15573 159 var INPUTS=[].slice.call(document.getElementsByClassName("inputcalc"));
pascal@15573 160 INPUTS.forEach(function(elm) {
pascal@15573 161 elm.onfocus = function(e) {
pascal@15573 162 e.target.value = e.target.title || "";
pascal@15573 163 };
pascal@15573 164 elm.onblur = function(e) {
pascal@15573 165 setCell(e.target, e.target.value);
pascal@15573 166 computeAll();
pascal@15573 167 };
pascal@15573 168 var calcid = elm.id.substring(0,4), cellid = elm.id.substring(4);
pascal@15573 169 var getter = function() {
pascal@15573 170 var value = elm.title || "";
pascal@15573 171 if (value.charAt(0) == "=")
pascal@15573 172 with (DATA[calcid]) return eval(value.substring(1));
pascal@17794 173 else return (value == "" || isNaN(value)) ? value : parseFloat(value);
pascal@15573 174 };
pascal@15573 175 Object.defineProperty(DATA[calcid], cellid, {get:getter});
pascal@15573 176 Object.defineProperty(DATA[calcid], cellid.toLowerCase(), {get:getter});
pascal@15573 177 });
pascal@15573 178 (window.computeAll = function() {
pascal@15573 179 INPUTS.forEach(function(elm) {
pascal@15573 180 var calcid = elm.id.substring(0,4), cellid = elm.id.substring(4);
pascal@15573 181 try { elm.value = DATA[calcid][cellid]; } catch(e) {} });
pascal@15573 182 })();
pascal@15573 183 //-->
pascal@15573 184 </script>
pascal@15573 185 EOT;
pascal@15573 186 }
pascal@15573 187 $CONTENT = $this->newCONTENT;
pascal@15573 188 }
pascal@15573 189
pascal@15573 190 function template()
pascal@15573 191 {
pascal@15573 192 global $html;
pascal@15573 193 $html = preg_replace("/<\/head>/",
pascal@15573 194 "\t<style type=\"text/css\"> @import \"plugins/wkp_Calc.css\"; </style>\n</head>",
pascal@15573 195 $html);
pascal@15573 196 }
pascal@15573 197 }
pascal@15573 198 ?>