1<?php 2 3if (!defined('DOKU_INC')) die(); 4require_once(__DIR__ . '/../webcomponent.php'); 5 6 7/** 8 * Class syntax_plugin_webcomponent_math 9 */ 10class syntax_plugin_webcomponent_math extends DokuWiki_Syntax_Plugin 11{ 12 13 public const MATH_EXPRESSION = 'math_expression'; 14 15 16 /** 17 * Syntax Type 18 * 19 * Protected in order to say that we don't want it to be modified 20 * The mathjax javascript will take care of the rendering 21 * 22 * @return string 23 */ 24 public function getType() 25 { 26 return 'protected'; 27 } 28 29 /** 30 * @return array 31 * Allow which kind of plugin inside 32 * 33 * No one of array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs') 34 * because we manage self the content and we call self the parser 35 */ 36 public function getAllowedTypes() 37 { 38 return array(); 39 } 40 41 /** 42 * How Dokuwiki will add P element 43 * 44 * * 'normal' - The plugin can be used inside paragraphs 45 * * 'block' - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs 46 * * 'stack' - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs 47 * 48 * @see DokuWiki_Syntax_Plugin::getPType() 49 */ 50 function getPType() 51 { 52 return 'normal'; 53 } 54 55 /** 56 * 57 * @return int 58 */ 59 public function getSort() 60 { 61 return 195; 62 } 63 64 /** 65 * 66 * @param string $mode 67 */ 68 public function connectTo($mode) 69 { 70 71 // Add the entry patterns 72 foreach (self::getElements() as $element) { 73 74 $pattern = webcomponent::getLookAheadPattern($element); 75 $this->Lexer->addEntryPattern($pattern, $mode, 'plugin_' . webcomponent::PLUGIN_NAME . '_' . $this->getPluginComponent()); 76 77 } 78 79 80 } 81 82 public function postConnect() 83 { 84 85 foreach (self::getElements() as $element) { 86 $this->Lexer->addExitPattern('</' . $element . '>', 'plugin_' . webcomponent::PLUGIN_NAME . '_' . $this->getPluginComponent()); 87 } 88 89 } 90 91 /** 92 * 93 * @param string $match The text matched by the patterns 94 * @param int $state The lexer state for the match 95 * @param int $pos The character position of the matched text 96 * @param Doku_Handler $handler The Doku_Handler object 97 * @return array Return an array with all data you want to use in render 98 */ 99 public function handle($match, $state, $pos, Doku_Handler $handler) 100 { 101 // A metadata to tell if the page has a math expression or not 102 // Use in the action plugin to add or not the library 103 global $ID; 104 p_set_metadata($ID,array(syntax_plugin_webcomponent_math::MATH_EXPRESSION =>false)); 105 106 // The element is also needed by mathjax 107 // pass the whole thing 108 return array( 109 0 => $match 110 ); 111 } 112 113 /** 114 * Handles the actual output creation. 115 * 116 * @param $mode string output format being rendered 117 * @param $renderer Doku_Renderer the current renderer object 118 * @param $data array data created by handler() 119 * @return boolean rendered correctly? 120 */ 121 public function render($mode, Doku_Renderer $renderer, $data) 122 { 123 124 $content = $data[0]; 125 switch ($mode) { 126 case 'xhtml': 127 /** @var Doku_Renderer_xhtml $renderer */ 128 $renderer->doc .= $renderer->_xmlEntities($content); 129 break; 130 131 case 'odt': 132 /** @var Doku_Renderer_xhtml $renderer */ 133 $renderer->doc .= $renderer->_xmlEntities($content); 134 break; 135 136 case 'latexport': 137 // Pass math expressions to latexport renderer 138 $renderer->mathjax_content($content); 139 break; 140 141 case 'metadata': 142 // Adding a meta to say that there is a math expression 143 global $ID; 144 /** @var Doku_Renderer_metadata $renderer */ 145 $renderer->meta[self::MATH_EXPRESSION]=true; 146 $renderer->persistent[self::MATH_EXPRESSION]=true; 147 148 // TODO: What if the page is changed and that there is no math syntax anymore 149 // Add a syntax to suppress the expression 150 break; 151 152 default: 153 $renderer->doc .= $renderer->$data; 154 break; 155 156 } 157 158 return true; 159 160 } 161 162 static public function getElements() 163 { 164 return webcomponent::getTags(get_called_class()); 165 } 166 167 public static function getComponentName() 168 { 169 return webcomponent::getTagName(get_called_class()); 170 } 171 172} 173 174