1<?php 2 3// must be run within Dokuwiki 4if(!defined('DOKU_INC')) die(); 5 6require_once DOKU_PLUGIN . 'latexport/implementation/decorator.php'; 7 8/** 9 * Adapts the mathjax expressions to latex. 10 * - If a $$ contains any \begin, then it is removed. 11 * - Transforms $$ into \begin{equation} and \end{equation}. 12 * - Groups multiple $$ into the same block of \begin{gather} \end{gather}. 13 * - Leaves inline equations surrounded by $$. 14 * 15 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 16 * @author Jean-Michel Gonet <jmgonet@yahoo.com> 17 */ 18class DecoratorMath extends Decorator { 19 20 const NOT_IN_EQUATION = 1000; 21 const IN_EQUATION = 1001; 22 23 private $state; 24 25 private $equation; 26 27 /** 28 * Class constructor. 29 * @param archive Will receive the content of the document. 30 */ 31 function __construct($decorator) { 32 parent::__construct($decorator); 33 $this->state = DecoratorMath::NOT_IN_EQUATION; 34 } 35 36 /** 37 * Receives mathematic formula from Mathjax plugin. 38 * Sometimes a formula is split across several calls. 39 * Formula is finished when any other command is called. 40 */ 41 function mathjax_content($formula) { 42 if ($this->state == DecoratorMath::NOT_IN_EQUATION) { 43 $this->equation = $formula; 44 $this->state = DecoratorMath::IN_EQUATION; 45 } else { 46 $this->equation = $this->equation.$formula; 47 } 48 } 49 50 /** 51 * Sometimes a formula is split across several calls. 52 * Formula is finished when any other command is called. 53 */ 54 function any_command() { 55 if ($this->state == DecoratorMath::IN_EQUATION) { 56 $this->decorator->mathjax_content($this->processEquation($this->equation)); 57 $this->state = DecoratorMath::NOT_IN_EQUATION; 58 } 59 } 60 61 /** 62 * Transforms the equation according to the rendering rules. 63 * - Formula surrounded (inline) by $ ... $ is transformed to \( ... \) 64 * - Formula surrounded by $$ ... $$ or \[ ... \] is surrounded with \begin{equation} ... \end{equation} 65 * - Formula containing any amsmath command is left as is. 66 * @param String $equation The equation. 67 * @return String The escaped equation. 68 */ 69 private function processEquation($equation) { 70 if (substr( $equation, 0, 2 ) === "$$" || substr( $equation, 0, 2 ) === '\\[') { 71 return $this->processDisplayEquation($equation); 72 } else if (substr( $equation, 0, 1 ) === "$") { 73 return $this->processInlineEquation($equation); 74 } else { 75 return $this->processAmsMathEquation($equation); 76 } 77 } 78 79 private function processDisplayEquation($equation) { 80 $trimmedEquation = substr($equation, 2, strlen($equation) - 4); 81 $trimmedEquation = trim($trimmedEquation); 82 $trimmedEquation = $this->removeTagCommand($trimmedEquation); 83 return "\\begin{equation}\r\n $trimmedEquation\r\n\\end{equation}\r\n"; 84 } 85 86 private function processInlineEquation($equation) { 87 $trimmedEquation = trim($this->removeTagCommand($equation), '$ '); 88 return '\\('.$trimmedEquation.'\\)'; 89 } 90 91 private function processAmsMathEquation($equation) { 92 return $equation; 93 } 94 95 /** 96 * The tag command, although supported in Mathjax, it is not well handled by the 'equation' 97 * environment. 98 * @param String $equation The equation. 99 * @return String The escaped equation. 100 */ 101 private function removeTagCommand($equation) { 102 return preg_replace('/\\\\tag\{[^}]+\}/', '', $equation); 103 } 104} 105