1<?php 2 3use ComboStrap\PluginUtility; 4 5if (!defined('DOKU_INC')) die(); 6require_once(__DIR__ . '/../ComboStrap/PluginUtility.php'); 7 8 9/** 10 * Class syntax_plugin_combo_math 11 */ 12class syntax_plugin_combo_math extends DokuWiki_Syntax_Plugin 13{ 14 15 const TAG = "math"; 16 17 18 /** 19 * Syntax Type 20 * 21 * Protected in order to say that we don't want it to be modified 22 * The mathjax javascript will take care of the rendering 23 * 24 * @return string 25 */ 26 public function getType() 27 { 28 return 'substition'; 29 } 30 31 /** 32 * @return array 33 * Allow which kind of plugin inside 34 * 35 * No one of array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs') 36 * because we manage self the content and we call self the parser 37 */ 38 public function getAllowedTypes() 39 { 40 return array(); 41 } 42 43 /** 44 * How Dokuwiki will add P element 45 * 46 * * 'normal' - The plugin can be used inside paragraphs 47 * * 'block' - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs 48 * * 'stack' - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs 49 * 50 * @see DokuWiki_Syntax_Plugin::getPType() 51 */ 52 function getPType() 53 { 54 return 'normal'; 55 } 56 57 /** 58 * 59 * @return int 60 */ 61 public function getSort() 62 { 63 return 195; 64 } 65 66 /** 67 * 68 * @param string $mode 69 */ 70 public function connectTo($mode) 71 { 72 73 // Add the entry patterns 74 foreach (self::getTags() as $element) { 75 76 $pattern = PluginUtility::getLeafContainerTagPattern($element); 77 $this->Lexer->addSpecialPattern($pattern, $mode, PluginUtility::getModeFromTag($this->getPluginComponent())); 78 79 } 80 81 82 } 83 84 85 /** 86 * 87 * @param string $match The text matched by the patterns 88 * @param int $state The lexer state for the match 89 * @param int $pos The character position of the matched text 90 * @param Doku_Handler $handler The Doku_Handler object 91 * @return array Return an array with all data you want to use in render 92 */ 93 public function handle($match, $state, $pos, Doku_Handler $handler) 94 { 95 96 return array($match); 97 } 98 99 /** 100 * Render the output 101 * @param string $format 102 * @param Doku_Renderer $renderer 103 * @param array $data - what the function handle() return'ed 104 * @return boolean - rendered correctly? (however, returned value is not used at the moment) 105 * @see DokuWiki_Syntax_Plugin::render() 106 * 107 * 108 */ 109 function render($format, Doku_Renderer $renderer, $data) 110 { 111 112 list($content) = $data; 113 switch ($format) { 114 case 'xhtml': 115 case 'odt': 116 /** @var Doku_Renderer_xhtml $renderer */ 117 118 /** 119 * MathJax finds the item via the the FindMath Interface 120 * 121 * FindMath Interface that has three implementations (https://github.com/mathjax/MathJax-src/blob/master/ts/core/FindMath.ts) 122 * * tex (https://github.com/mathjax/MathJax-src/blob/master/ts/input/tex.ts) 123 * * asciimath (https://github.com/mathjax/MathJax-src/blob/master/ts/input/asciimath.ts) 124 * * mathml (https://github.com/mathjax/MathJax-src/blob/master/ts/input/mathml.ts) 125 * 126 * For Tex and AsciiMath, FindMath will all text text 127 * and scan them to find the math formula through delimiter. 128 * The ProtoItem interface (MathJax Item) stores the start and end location - https://github.com/mathjax/MathJax-src/blob/master/ts/core/MathItem.ts#L219 129 * 130 * We output then the math expression as character data that will end up 131 * in a text node. 132 */ 133 $renderer->doc .= $renderer->_xmlEntities($content) . DOKU_LF; 134 135 /** 136 * CSS 137 */ 138 $snippetManager = PluginUtility::getSnippetManager(); 139 $snippetManager->attachCssInternalStyleSheet(self::TAG); 140 141 /** 142 * Javascript config 143 */ 144 $headHtmlElement = <<<EOD 145MathJax.Hub.Config({ 146 showProcessingMessages: true, 147 extensions: ["tex2jax.js","TeX/AMSmath.js","TeX/AMSsymbols.js"], 148 jax: ["input/TeX", "output/HTML-CSS"], 149 tex2jax: { 150 inlineMath: [ ["<math>","</math>"]], 151 displayMath: [ ["<MATH>","</MATH>"] ], 152 processEscapes: true, 153 scale:120 154 }, 155 "HTML-CSS": { fonts: ["TeX"] } 156}); 157EOD; 158 159 $snippetManager 160 ->attachJavascriptFromComponentId( 161 self::TAG, 162 $headHtmlElement 163 ) 164 ->addHtmlAttribute("type", "text/x-mathjax-config"); 165 $snippetManager->attachRemoteJavascriptLibrary( 166 self::TAG, 167 "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js" 168 ) 169 ->setDoesManipulateTheDomOnRun(false); 170 break; 171 172 case 'latexport': 173 // Pass math expressions to latexport renderer 174 /** @noinspection PhpUndefinedMethodInspection */ 175 $renderer->mathjax_content($content); 176 break; 177 178 } 179 180 return true; 181 182 } 183 184 static public function getTags(): array 185 { 186 return PluginUtility::getTags(get_called_class()); 187 } 188 189 public static function getComponentName(): string 190 { 191 return PluginUtility::getTagName(get_called_class()); 192 } 193 194} 195 196