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