xref: /plugin/combo/syntax/highlightmd.php (revision 4cadd4f8c541149bdda95f080e38a6d4e3a640ca)
1<?php
2
3use ComboStrap\PluginUtility;
4
5
6/**
7 *
8 * Known as code
9 * https://spec.commonmark.org/0.30/#code-spans
10 *
11 * note supported but specific highlight is done with two `==`
12 * in some processor
13 * https://www.markdownguide.org/extended-syntax/#highlight
14 *
15 */
16class syntax_plugin_combo_highlightmd extends DokuWiki_Syntax_Plugin
17{
18
19
20    const TAG = "highlightmd";
21    // Only on one line
22
23    /**
24     * Only on one line, otherwise
25     * if it's not closed, it will eat all other syntaqx
26     */
27    const ENTRY_PATTERN = "`[^\n]*(?=`)(?!\n)";
28
29    const EXIT_PATTERN = "`";
30    const CANONICAL = self::TAG;
31
32    public function getSort(): int
33    {
34
35        return 200;
36    }
37
38    public function getType(): string
39    {
40        return 'formatting';
41    }
42
43
44    /**
45     *
46     * How Dokuwiki will add P element
47     *
48     *  * 'normal' - The plugin can be used inside paragraphs (inline)
49     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
50     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
51     *
52     * @see DokuWiki_Syntax_Plugin::getPType()
53     *
54     * This is the equivalent of inline or block for css
55     */
56    public function getPType(): string
57    {
58        return 'normal';
59    }
60
61    /**
62     * @return array
63     * Allow which kind of plugin inside
64     *
65     * No one of array('baseonly','container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs')
66     * because we manage self the content and we call self the parser
67     *
68     * Return an array of one or more of the mode types {@link $PARSER_MODES} in Parser.php
69     */
70    function getAllowedTypes(): array
71    {
72        return array('formatting', 'substition', 'protected', 'disabled');
73    }
74
75
76    public function connectTo($mode)
77    {
78
79        $this->Lexer->addEntryPattern(self::ENTRY_PATTERN, $mode, PluginUtility::getModeFromTag($this->getPluginComponent()));
80
81
82    }
83
84    public function postConnect()
85    {
86
87        $this->Lexer->addExitPattern(self::EXIT_PATTERN, PluginUtility::getModeFromTag($this->getPluginComponent()));
88
89    }
90
91
92    /**
93     * Handle the syntax
94     *
95     * At the end of the parser, the `section_open` and `section_close` calls
96     * are created in {@link action_plugin_combo_headingpostprocessing}
97     * and the text inside for the toc is captured
98     *
99     * @param string $match
100     * @param int $state
101     * @param int $pos
102     * @param Doku_Handler $handler
103     * @return array
104     */
105    public function handle($match, $state, $pos, Doku_Handler $handler): array
106    {
107        switch ($state) {
108
109            case DOKU_LEXER_EXIT:
110            case DOKU_LEXER_ENTER:
111
112                $content = substr($match, 1);
113                return array(
114                    PluginUtility::STATE => $state,
115                    PluginUtility::PAYLOAD => $content,
116                );
117            case DOKU_LEXER_UNMATCHED :
118
119                return PluginUtility::handleAndReturnUnmatchedData(self::TAG, $match, $handler);
120
121        }
122        return array();
123    }
124
125    public function render($format, Doku_Renderer $renderer, $data): bool
126    {
127
128        switch ($format) {
129            case "xhtml":
130                /**
131                 * @var Doku_Renderer_xhtml $renderer
132                 */
133                $state = $data[PluginUtility::STATE];
134                switch ($state) {
135
136                    case DOKU_LEXER_ENTER:
137                        $renderer->doc .= syntax_plugin_combo_highlightwiki::getOpenTagHighlight(self::TAG) . $data[PluginUtility::PAYLOAD];
138                        return true;
139                    case DOKU_LEXER_UNMATCHED:
140                        $renderer->doc .= PluginUtility::renderUnmatched($data);
141                        return true;
142                    case DOKU_LEXER_EXIT:
143                        $renderer->doc .= "</mark>";
144                        return true;
145
146                }
147                break;
148            case "metadata":
149                /**
150                 * @var Doku_Renderer_metadata $renderer
151                 */
152                $state = $data[PluginUtility::STATE];
153                switch ($state) {
154                    case DOKU_LEXER_ENTER:
155                        $renderer->doc .= $data[PluginUtility::PAYLOAD];
156                        return true;
157                    case DOKU_LEXER_UNMATCHED:
158                        $renderer->doc .= PluginUtility::renderUnmatched($data);
159                }
160                break;
161        }
162
163        return false;
164    }
165
166    /**
167     * @param $match
168     * @return int
169     */
170    public
171    function getLevelFromMatch($match)
172    {
173        return 7 - strlen(trim($match));
174    }
175
176
177    private
178    function enableWikiHeading($mode)
179    {
180
181
182        /**
183         * Basically all mode that are not `base`
184         * To not take the dokuwiki heading
185         */
186        if (!(in_array($mode, ['base', 'header', 'table']))) {
187            return true;
188        } else {
189            return PluginUtility::getConfValue(self::CONF_WIKI_HIGHLIGHT_ENABLE, self::CONF_DEFAULT_WIKI_ENABLE_VALUE);
190        }
191
192
193    }
194
195
196}
197