1007225e5Sgerardnico<?php 2007225e5Sgerardnico 3007225e5Sgerardnicouse ComboStrap\PluginUtility; 4007225e5Sgerardnico 5007225e5Sgerardnicoif (!defined('DOKU_INC')) die(); 637748cd8SNickeaurequire_once(__DIR__ . '/../ComboStrap/PluginUtility.php'); 7007225e5Sgerardnico 8007225e5Sgerardnico 9007225e5Sgerardnico/** 10007225e5Sgerardnico * Class syntax_plugin_combo_math 11007225e5Sgerardnico */ 12007225e5Sgerardnicoclass syntax_plugin_combo_math extends DokuWiki_Syntax_Plugin 13007225e5Sgerardnico{ 14007225e5Sgerardnico 155f891b7eSNickeau const TAG = "math"; 165f891b7eSNickeau 17007225e5Sgerardnico 18007225e5Sgerardnico /** 19007225e5Sgerardnico * Syntax Type 20007225e5Sgerardnico * 21007225e5Sgerardnico * Protected in order to say that we don't want it to be modified 22007225e5Sgerardnico * The mathjax javascript will take care of the rendering 23007225e5Sgerardnico * 24007225e5Sgerardnico * @return string 25007225e5Sgerardnico */ 26007225e5Sgerardnico public function getType() 27007225e5Sgerardnico { 28007225e5Sgerardnico return 'substition'; 29007225e5Sgerardnico } 30007225e5Sgerardnico 31007225e5Sgerardnico /** 32007225e5Sgerardnico * @return array 33007225e5Sgerardnico * Allow which kind of plugin inside 34007225e5Sgerardnico * 35007225e5Sgerardnico * No one of array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs') 36007225e5Sgerardnico * because we manage self the content and we call self the parser 37007225e5Sgerardnico */ 38007225e5Sgerardnico public function getAllowedTypes() 39007225e5Sgerardnico { 40007225e5Sgerardnico return array(); 41007225e5Sgerardnico } 42007225e5Sgerardnico 43007225e5Sgerardnico /** 44007225e5Sgerardnico * How Dokuwiki will add P element 45007225e5Sgerardnico * 46007225e5Sgerardnico * * 'normal' - The plugin can be used inside paragraphs 47007225e5Sgerardnico * * 'block' - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs 48007225e5Sgerardnico * * 'stack' - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs 49007225e5Sgerardnico * 50007225e5Sgerardnico * @see DokuWiki_Syntax_Plugin::getPType() 51007225e5Sgerardnico */ 52007225e5Sgerardnico function getPType() 53007225e5Sgerardnico { 54007225e5Sgerardnico return 'normal'; 55007225e5Sgerardnico } 56007225e5Sgerardnico 57007225e5Sgerardnico /** 58007225e5Sgerardnico * 59007225e5Sgerardnico * @return int 60007225e5Sgerardnico */ 61007225e5Sgerardnico public function getSort() 62007225e5Sgerardnico { 63007225e5Sgerardnico return 195; 64007225e5Sgerardnico } 65007225e5Sgerardnico 66007225e5Sgerardnico /** 67007225e5Sgerardnico * 68007225e5Sgerardnico * @param string $mode 69007225e5Sgerardnico */ 70007225e5Sgerardnico public function connectTo($mode) 71007225e5Sgerardnico { 72007225e5Sgerardnico 73007225e5Sgerardnico // Add the entry patterns 74007225e5Sgerardnico foreach (self::getTags() as $element) { 75007225e5Sgerardnico 76007225e5Sgerardnico $pattern = PluginUtility::getLeafContainerTagPattern($element); 779337a630SNickeau $this->Lexer->addSpecialPattern($pattern, $mode, PluginUtility::getModeFromTag($this->getPluginComponent())); 78007225e5Sgerardnico 79007225e5Sgerardnico } 80007225e5Sgerardnico 81007225e5Sgerardnico 82007225e5Sgerardnico } 83007225e5Sgerardnico 84007225e5Sgerardnico 85007225e5Sgerardnico /** 86007225e5Sgerardnico * 87007225e5Sgerardnico * @param string $match The text matched by the patterns 88007225e5Sgerardnico * @param int $state The lexer state for the match 89007225e5Sgerardnico * @param int $pos The character position of the matched text 90007225e5Sgerardnico * @param Doku_Handler $handler The Doku_Handler object 91007225e5Sgerardnico * @return array Return an array with all data you want to use in render 92007225e5Sgerardnico */ 93007225e5Sgerardnico public function handle($match, $state, $pos, Doku_Handler $handler) 94007225e5Sgerardnico { 95007225e5Sgerardnico 96007225e5Sgerardnico return array($match); 97007225e5Sgerardnico } 98007225e5Sgerardnico 99007225e5Sgerardnico /** 100007225e5Sgerardnico * Render the output 101007225e5Sgerardnico * @param string $format 102007225e5Sgerardnico * @param Doku_Renderer $renderer 103007225e5Sgerardnico * @param array $data - what the function handle() return'ed 104007225e5Sgerardnico * @return boolean - rendered correctly? (however, returned value is not used at the moment) 105007225e5Sgerardnico * @see DokuWiki_Syntax_Plugin::render() 106007225e5Sgerardnico * 107007225e5Sgerardnico * 108007225e5Sgerardnico */ 109007225e5Sgerardnico function render($format, Doku_Renderer $renderer, $data) 110007225e5Sgerardnico { 111007225e5Sgerardnico 112007225e5Sgerardnico list($content) = $data; 113007225e5Sgerardnico switch ($format) { 114007225e5Sgerardnico case 'xhtml': 115007225e5Sgerardnico case 'odt': 116007225e5Sgerardnico /** @var Doku_Renderer_xhtml $renderer */ 117*04fd306cSNickeau 118*04fd306cSNickeau /** 119*04fd306cSNickeau * MathJax finds the item via the the FindMath Interface 120*04fd306cSNickeau * 121*04fd306cSNickeau * FindMath Interface that has three implementations (https://github.com/mathjax/MathJax-src/blob/master/ts/core/FindMath.ts) 122*04fd306cSNickeau * * tex (https://github.com/mathjax/MathJax-src/blob/master/ts/input/tex.ts) 123*04fd306cSNickeau * * asciimath (https://github.com/mathjax/MathJax-src/blob/master/ts/input/asciimath.ts) 124*04fd306cSNickeau * * mathml (https://github.com/mathjax/MathJax-src/blob/master/ts/input/mathml.ts) 125*04fd306cSNickeau * 126*04fd306cSNickeau * For Tex and AsciiMath, FindMath will all text text 127*04fd306cSNickeau * and scan them to find the math formula through delimiter. 128*04fd306cSNickeau * 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*04fd306cSNickeau * 130*04fd306cSNickeau * We output then the math expression as character data that will end up 131*04fd306cSNickeau * in a text node. 132*04fd306cSNickeau */ 133007225e5Sgerardnico $renderer->doc .= $renderer->_xmlEntities($content) . DOKU_LF; 1345f891b7eSNickeau 1355f891b7eSNickeau /** 1365f891b7eSNickeau * CSS 1375f891b7eSNickeau */ 1384cadd4f8SNickeau $snippetManager = PluginUtility::getSnippetManager(); 139*04fd306cSNickeau $snippetManager->attachCssInternalStyleSheet(self::TAG); 1405f891b7eSNickeau 1415f891b7eSNickeau /** 1425f891b7eSNickeau * Javascript config 1435f891b7eSNickeau */ 1445f891b7eSNickeau $headHtmlElement = <<<EOD 1455f891b7eSNickeauMathJax.Hub.Config({ 1465f891b7eSNickeau showProcessingMessages: true, 1475f891b7eSNickeau extensions: ["tex2jax.js","TeX/AMSmath.js","TeX/AMSsymbols.js"], 1485f891b7eSNickeau jax: ["input/TeX", "output/HTML-CSS"], 1495f891b7eSNickeau tex2jax: { 1505f891b7eSNickeau inlineMath: [ ["<math>","</math>"]], 1515f891b7eSNickeau displayMath: [ ["<MATH>","</MATH>"] ], 1525f891b7eSNickeau processEscapes: true, 1535f891b7eSNickeau scale:120 1545f891b7eSNickeau }, 1555f891b7eSNickeau "HTML-CSS": { fonts: ["TeX"] } 1565f891b7eSNickeau}); 1575f891b7eSNickeauEOD; 1585f891b7eSNickeau 1594cadd4f8SNickeau $snippetManager 160*04fd306cSNickeau ->attachJavascriptFromComponentId( 1614cadd4f8SNickeau self::TAG, 1624cadd4f8SNickeau $headHtmlElement 1635f891b7eSNickeau ) 1644cadd4f8SNickeau ->addHtmlAttribute("type", "text/x-mathjax-config"); 1654cadd4f8SNickeau $snippetManager 166*04fd306cSNickeau ->attachRemoteJavascriptLibrary( 1674cadd4f8SNickeau self::TAG, 1684cadd4f8SNickeau "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js" 1694cadd4f8SNickeau ) 1704cadd4f8SNickeau ->setDoesManipulateTheDomOnRun(false); 171007225e5Sgerardnico break; 172007225e5Sgerardnico 173007225e5Sgerardnico case 'latexport': 174007225e5Sgerardnico // Pass math expressions to latexport renderer 175*04fd306cSNickeau /** @noinspection PhpUndefinedMethodInspection */ 176007225e5Sgerardnico $renderer->mathjax_content($content); 177007225e5Sgerardnico break; 178007225e5Sgerardnico 179007225e5Sgerardnico default: 180007225e5Sgerardnico $renderer->doc .= $renderer->$data; 181007225e5Sgerardnico break; 182007225e5Sgerardnico 183007225e5Sgerardnico } 184007225e5Sgerardnico 185007225e5Sgerardnico return true; 186007225e5Sgerardnico 187007225e5Sgerardnico } 188007225e5Sgerardnico 189*04fd306cSNickeau static public function getTags(): array 190007225e5Sgerardnico { 191007225e5Sgerardnico return PluginUtility::getTags(get_called_class()); 192007225e5Sgerardnico } 193007225e5Sgerardnico 194*04fd306cSNickeau public static function getComponentName(): string 195007225e5Sgerardnico { 196007225e5Sgerardnico return PluginUtility::getTagName(get_called_class()); 197007225e5Sgerardnico } 198007225e5Sgerardnico 199007225e5Sgerardnico} 200007225e5Sgerardnico 201