1<?php
2/**
3 * DokuWiki Plugin TikZJax (Syntax Component)
4 *
5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author Jakub pelc <admin@swpelc.eu>
7 */
8
9if (!defined('DOKU_INC')) die();
10
11class syntax_plugin_tikzjax extends DokuWiki_Syntax_Plugin {
12
13    /**
14     * Get the type of syntax this plugin defines.
15     *
16     * @return string 'protected' allows nested content
17     */
18    public function getType() {
19        return 'protected';
20    }
21
22    /**
23     * Define how this plugin is handled regarding paragraphs.
24     *
25     * @return string 'block' ensures content is handled as a block element
26     */
27    public function getPType() {
28        return 'block';
29    }
30
31    /**
32     * Sort order of this plugin
33     *
34     * @return int
35     */
36    public function getSort() {
37        return 999;
38    }
39
40    /**
41     * Connect lookup pattern to lexer.
42     *
43     * @param string $mode
44     */
45    public function connectTo($mode) {
46        $this->Lexer->addEntryPattern('<tikzjax>(?=.*?</tikzjax>)', $mode, 'plugin_tikzjax');
47    }
48
49    /**
50     * Add exit pattern for plugin
51     */
52    public function postConnect() {
53        $this->Lexer->addExitPattern('</tikzjax>', 'plugin_tikzjax');
54    }
55
56    /**
57     * Handle matches of the plugin.
58     *
59     * @param string $match
60     * @param int $state
61     * @param int $pos
62     * @param Doku_Handler $handler
63     * @return array
64     */
65    public function handle($match, $state, $pos, Doku_Handler $handler) {
66        switch ($state) {
67            case DOKU_LEXER_ENTER:
68                return ['state' => 'enter'];
69            case DOKU_LEXER_UNMATCHED:
70                return ['state' => 'content', 'content' => $match];
71            case DOKU_LEXER_EXIT:
72                return ['state' => 'exit'];
73        }
74        return [];
75    }
76
77    /**
78     * Render the output
79     *
80     * @param string $mode
81     * @param Doku_Renderer $renderer
82     * @param array $data
83     * @return bool
84     */
85    public function render($mode, Doku_Renderer $renderer, $data) {
86        if ($mode !== 'xhtml') return false;
87
88        if ($data['state'] === 'enter') {
89            $renderer->doc .= '<script type="text/tikz">';
90        } elseif ($data['state'] === 'content') {
91            $renderer->doc .= html_entity_decode(htmlspecialchars($data['content']));
92        } elseif ($data['state'] === 'exit') {
93            $renderer->doc .= '</script>';
94            // Add inline style to increase rendered SVG size
95            $renderer->doc .= '<style>
96                svg { width: 100%; height: auto; }
97            </style>';
98        }
99
100        return true;
101    }
102}