diff --git a/mathexphtml.php b/MathExpHtml.php similarity index 67% rename from mathexphtml.php rename to MathExpHtml.php index 1aa3448..0de174c 100644 --- a/mathexphtml.php +++ b/MathExpHtml.php @@ -1,19 +1,19 @@ ', ',' )); + $this->tokens = $this->str2tokens($str); } - function operators() + + public function printTokens() + { + echo "
";
+        foreach ($this->tokens as $token) {
+            $token = trim($token);
+            echo $token . "  is " . $this->tokentype($token) . "
"; + } + echo "
"; + } + + public function gethtml() + { + $tokens = $this->parsepar($this->tokens); + echo "" . $this->exphtml($tokens) . ""; + } + + private function operators() { return _OPERATORS; } - function str2tokens($str) + + private function str2tokens($str) { $tokens = preg_split('/([<>()*\/=^+-])\s*|([\d.]+)\s*|(\w+)\s*|({\w+})\s*/', $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); + return $tokens; } - function tokentype($token) + + private function tokentype($token) { return (is_numeric($token) ? "value" : (in_array($token, _OPERATORS) ? "operator" : (preg_match('/^[\w-]+$/', $token) ? "alphanum" : (preg_match('/({\w+})/', $token)?"vector":"none")))); } - function mathhtml($a, $o, $b) + + private function mathhtml($a, $o, $b) { $html = ""; + switch ($o) { case '+': case '-': - case '=': case '<': case '>': case ',': $html = "$a $o $b"; - break; + break; + case '*': - $html = "$a • $b"; - break; + $html = "$a • $b"; + break; + case '^': $html = "$a$b"; - break; + break; + case '/': $html = "
"; $html .= "$a"; // numerator $html .= "/"; $html .= "$b"; // denominator $html .= "
"; - break; + break; } + return ($html); } - function testknownoperator($token){ + + private function testknownoperator($token) + { $pattern = "/([(),+])\s*/"; - //$str = strip_tags($token); $test = preg_split($pattern, $token, 8, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); - - //echo "
"; - //print_r($test); - //echo "
"; - $html = ""; - if (strip_tags($test[0]) == 'sum'){ $html = "". "".$test[4]."". "". "".$test[2]."". ""; - }/* - else if (strip_tags($test[0]) == 'int'){ - $html = "". - "".$test[4]."". - "". - "".$test[2]."". - ""; } - */ + return $html; } - function formatelement($tokens) + + private function formatelement($tokens) { $len = count($tokens); - for ($i = 0;$i < $len;$i++) - { + for ($i = 0;$i < $len;$i++) { $a = $tokens[$i]; $b = ($i < $len - 1) ? trim($tokens[$i + 1]) : " "; - if ($this->tokentype($a) == "alphanum") - { - if ($b[0] == '('){ + + if ($this->tokentype($a) == "alphanum") { + if ($b[0] == '(') { $a = "$a"; + } else { + $a = "$a"; } - else $a = "$a"; - } - else if ($this->tokentype($a) == "value"){ + } elseif ($this->tokentype($a) == "value") { $a = "$a"; - } else if ($this->tokentype($a) == "vector"){ + } elseif ($this->tokentype($a) == "vector") { $a = str_replace(array("{", "}"), "", $a); $s = strlen($a); $a = " $a". "". ""; } + $tokens[$i] = $a; } + return $tokens; } - function parsepar($tokens) + private function parsepar($tokens) { $tokens = $this->formatelement($tokens); $pos = 0; $len = count($tokens); $level = 0; - while ($pos < $len) - { + while ($pos < $len) { $a = $tokens[$pos]; - while ($a != "(" && $pos < $len) - { + + while ($a != "(" && $pos < $len) { $pos++; $a = $tokens[$pos]; } - while ($a != ")" && $pos < $len) - { - if ($a == "(") - { + + while ($a != ")" && $pos < $len) { + if ($a == "(") { $start = $pos; $level++; } + $pos++; $a = $tokens[$pos]; } - if ($a == ")") - { + + if ($a == ")") { $end = $pos; $level--; $subtokens = array_slice($tokens, $start + 1, $end - $start - 1); array_splice($tokens, $start + 1, $end - $start); $tokens[$start] = "(" . $this->exphtml($subtokens) . ")"; - //echo "sub ".$subtokens[0]."=>".count($subtokens)."
"; $pos = $start; } + $pos++; } - /* - print_r($tokens); - echo "
"; - print_r($subtokens); - echo "
"; - echo "level ".$level."
"; - */ - if ($level != 0) $tokens = $this->parsepar($tokens); + + if ($level != 0) { + $tokens = $this->parsepar($tokens); + } + return $tokens; } - function exphtml($tokens) + + private function exphtml($tokens) { $len = count($tokens); - if ($len <= 2) - { + if ($len <= 2) { return $tokens[0]; } - // merge function - for ($i = 0;$i < $len;$i++) - { + + for ($i = 0;$i < $len;$i++) { $a = $tokens[$i]; $b = ($i < $len - 1) ? trim($tokens[$i + 1]) : " "; - if ($this->tokentype(strip_tags($a)) == "alphanum") - { - if ($b[0] == '('){ + if ($this->tokentype(strip_tags($a)) == "alphanum") { + if ($b[0] == '(') { $tokens[$i] = $a . $b; array_splice($tokens, $i + 1, 1); $html = $this->testknownoperator($tokens[$i]); - if ($html != "") $tokens[$i] = $html; + if ($html != "") { + $tokens[$i] = $html; + } } } } + $len = count($tokens); - //echo "length ".$len."
"; $pos = 0; - while ($pos < $len - 2) - { + while ($pos < $len - 2) { $a = $tokens[$pos]; $o = $tokens[$pos + 1]; $b = $tokens[$pos + 2]; - if ($this->tokentype($o) == "operator" && $o == '^') - { + if ($this->tokentype($o) == "operator" && $o == '^') { $a = $this->mathhtml($a, $o, $b); $tokens[$pos] = $a; array_splice($tokens, $pos + 1, 2); $len = count($tokens); + } else { + $pos += 2; } - else $pos += 2; } $pos = 0; - while ($pos < $len - 2) - { + while ($pos < $len - 2) { $a = $tokens[$pos]; $o = $tokens[$pos + 1]; $b = $tokens[$pos + 2]; - if ($this->tokentype($o) == "operator" && ($o == "/" || $o == "*")) - { + if ($this->tokentype($o) == "operator" && ($o == "/" || $o == "*")) { $a = $this->mathhtml($a, $o, $b); $tokens[$pos] = $a; array_splice($tokens, $pos + 1, 2); $len = count($tokens); } - else $pos += 2; + else { + $pos += 2; + } } $pos = 0; $a = $tokens[$pos]; - while ($pos < $len - 2) - { + while ($pos < $len - 2) { $o = $tokens[$pos + 1]; $b = $tokens[$pos + 2]; - if ($this->tokentype($o) == "operator") - { + if ($this->tokentype($o) == "operator") { $a = $this->mathhtml($a, $o, $b); } + $pos += 2; } + if ($pos < $len-1 && $tokens[$pos+1][0] == '(') { $a .= $tokens[$pos+1]; } return $a; } - function printtokens() - { - echo "
";
-        foreach ($this->tokens as $token)
-        {
-            $token = trim($token);
-            echo $token . "  is " . $this->tokentype($token) . "
"; - } - echo "
"; - echo "
"; - } - function gethtml() - { - $tokens = $this->parsepar($this->tokens); - //echo "
"; - //print_r($tokens); - //echo "
"; - echo "" . $this->exphtml($tokens) . ""; - } } - -?> diff --git a/README.md b/README.md index a9c78ba..c30e5af 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,44 @@ -![Math-Expression-to-HTML](mathexphtml.jpg) # Math-Expression-to-HTML -Produce html code from the mathematic expression string -## Check Demo -Visit following link and check demo in forum. -[Demo](https://edu.structsoftlab.com/forum/) +Produce html code from the mathematic expression string. +![Math-Expression-to-HTML](mathexphtml.jpg) + +## Demo version + +Visit following link and check demo in forum +[Demo](https://edu.structsoftlab.com/forum/). + +## Usage + +First include the `MathExpHtml.php` class in your file, and use the class as following to generate the HTML for the math expressions: + +```php +$expression = "a=sum(i=1,3)(23.5*{vec}-(((cos(2+θ/2)+asd9)^2)/4.5+sin(0.5*θ))/(20.06+π*(16))^2-26)"; + +$parser = new MathExpHtml($expression); +$parser->printTokens(); +$parser->gethtml(); +``` ## Features -Algorythm is very simple. -- String is tokenized using preg_split into array of tokens, + +Algorithm is very simple. + +- String is tokenized using `preg_split` into array of tokens, - Token types are value, alpha-numeric and operator. - Alpha numeric represents as a variable or function name. - There are some known functions such as summation sign sum(i=1, 5). - First tokens are simplify into simple expression inside the parenthesis. -- Nested parenthesis are alliwed. +- Nested parenthesis are allowed. - Simple inside () are convert into html code using predefined css classes. - Precedence are common as following order, ^, *,/,+.-. -- Multiple expressions of () may connected without operator, -- eg., (3+a/4)(sin(0.5*θ)) -- Vector variable can be used in written form enclosed with cali-bracket. -- eg., {vec} +- Multiple expressions of () may connected without operator eg., (3+a/4)(sin(0.5*θ)) +- Vector variable can be used in written form enclosed with cali-bracket eg., {vec}. + +## Licence + +This project is published under the Gnu General Public License see [the License File](LICENSE) for more information. ## Contact -Contact me for comercial use via mail winaungcho@gmail.com +Contact me for comercial use via mail winaungcho@gmail.com. diff --git a/example.php b/example.php index 72579c3..ef6f147 100644 --- a/example.php +++ b/example.php @@ -1,19 +1,20 @@ - +