1<?php
2/**
3 * Copyright (c) 2021. ComboStrap, Inc. and its affiliates. All Rights Reserved.
4 *
5 * This source code is licensed under the GPL license found in the
6 * COPYING  file in the root directory of this source tree.
7 *
8 * @license  GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html)
9 * @author   ComboStrap <support@combostrap.com>
10 *
11 */
12
13/**
14 * Plugin Webcode: Show webcode (Css, HTML) in a iframe
15 *
16 */
17
18// must be run within Dokuwiki
19use ComboStrap\CallStack;
20use ComboStrap\Dimension;
21use ComboStrap\Display;
22use ComboStrap\ExceptionBadState;
23use ComboStrap\ExceptionCompile;
24use ComboStrap\ExceptionNotFound;
25use ComboStrap\ExecutionContext;
26use ComboStrap\FetcherMarkup;
27use ComboStrap\FetcherMarkupWebcode;
28use ComboStrap\FetcherRawLocalPath;
29use ComboStrap\LogUtility;
30use ComboStrap\PluginUtility;
31use ComboStrap\TagAttribute\StyleAttribute;
32use ComboStrap\Tag\WebCodeTag;
33use ComboStrap\TagAttributes;
34use ComboStrap\WikiPath;
35use ComboStrap\XmlTagProcessing;
36
37
38/**
39 * Webcode
40 */
41class syntax_plugin_combo_webcode extends DokuWiki_Syntax_Plugin
42{
43
44    // In the action bar
45    // In the code
46
47
48    /**
49     * Syntax Type.
50     *
51     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
52     * @see https://www.dokuwiki.org/devel:syntax_plugins#syntax_types
53     *
54     * container because it may contain header in case of how to
55     */
56    public function getType()
57    {
58        return 'container';
59    }
60
61    public function getPType()
62    {
63        return "stack";
64    }
65
66
67    /**
68     * @return array
69     * Allow which kind of plugin inside
70     *
71     * array('container', 'baseonly','formatting', 'substition', 'protected', 'disabled', 'paragraphs')
72     *
73     */
74    public function getAllowedTypes()
75    {
76        return array('container', 'baseonly', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs');
77    }
78
79
80    public function accepts($mode)
81    {
82
83        return syntax_plugin_combo_preformatted::disablePreformatted($mode);
84
85    }
86
87    /**
88     * @see Doku_Parser_Mode::getSort()
89     * The mode (plugin) with the lowest sort number will win out
90     *
91     * See {@link Doku_Parser_Mode_code}
92     */
93    public function getSort()
94    {
95        return 99;
96    }
97
98    /**
99     * Called before any calls to ConnectTo
100     * @return void
101     */
102    function preConnect()
103    {
104    }
105
106    /**
107     * Create a pattern that will called this plugin
108     *
109     * @param string $mode
110     *
111     * All dokuwiki mode can be seen in the parser.php file
112     * @see Doku_Parser_Mode::connectTo()
113     */
114    public function connectTo($mode)
115    {
116
117        $pattern = XmlTagProcessing::getContainerTagPattern(WebCodeTag::TAG);
118        $this->Lexer->addEntryPattern($pattern, $mode, PluginUtility::getModeFromTag($this->getPluginComponent()));
119
120    }
121
122
123    // This where the addPattern and addExitPattern are defined
124    public function postConnect()
125    {
126        $this->Lexer->addExitPattern('</' . WebCodeTag::TAG . '>', PluginUtility::getModeFromTag($this->getPluginComponent()));
127    }
128
129
130    /**
131     * Handle the match
132     * You get the match for each pattern in the $match variable
133     * $state says if it's an entry, exit or match pattern
134     *
135     * This is an instruction block and is cached apart from the rendering output
136     * There is two caches levels
137     * This cache may be suppressed with the url parameters ?purge=true
138     *
139     * The returned values are cached in an array that will be passed to the render method
140     * The handle function goal is to parse the matched syntax through the pattern function
141     * and to return the result for use in the renderer
142     * This result is always cached until the page is modified.
143     * @param string $match
144     * @param int $state
145     * @param int $pos
146     * @param Doku_Handler $handler
147     * @return array|bool
148     * @throws Exception
149     * @see DokuWiki_Syntax_Plugin::handle()
150     *
151     */
152    public function handle($match, $state, $pos, Doku_Handler $handler)
153    {
154        switch ($state) {
155
156            case DOKU_LEXER_ENTER :
157
158                // Default
159                $defaultAttributes = WebCodeTag::getDefaultAttributes();
160
161                // Parse and create the call stack array
162                $knownTypes = WebCodeTag::getKnownTypes();
163                $tagAttributes = TagAttributes::createFromTagMatch($match, $defaultAttributes, $knownTypes);
164                $callStackArray = $tagAttributes->toCallStackArray();
165
166                return array(
167                    PluginUtility::STATE => $state,
168                    PluginUtility::ATTRIBUTES => $callStackArray
169                );
170
171
172            case DOKU_LEXER_UNMATCHED :
173
174                return PluginUtility::handleAndReturnUnmatchedData(WebCodeTag::TAG, $match, $handler);
175
176
177            case DOKU_LEXER_EXIT:
178
179                $array = WebCodeTag::handleExit($handler);
180                $array[PluginUtility::STATE] = $state;
181                return $array;
182
183
184        }
185        return false;
186
187    }
188
189    /**
190     * Render the output
191     * @param string $mode
192     * @param Doku_Renderer $renderer
193     * @param array $data - what the function handle() return'ed
194     * @return bool - rendered correctly (not used)
195     *
196     * The rendering process
197     * @see DokuWiki_Syntax_Plugin::render()
198     *
199     */
200    public function render($mode, Doku_Renderer $renderer, $data): bool
201    {
202        // The $data variable comes from the handle() function
203        //
204        // $mode = 'xhtml' means that we output html
205        // There is other mode such as metadata where you can output data for the headers (Not 100% sure)
206        if ($mode == 'xhtml') {
207
208
209            /** @var Doku_Renderer_xhtml $renderer */
210
211            $state = $data[PluginUtility::STATE];
212            switch ($state) {
213
214
215                case DOKU_LEXER_UNMATCHED :
216
217                    $renderer->doc .= PluginUtility::renderUnmatched($data);
218                    break;
219                case DOKU_LEXER_EXIT :
220                    $callStackArray = $data[PluginUtility::ATTRIBUTES];
221                    $tagAttributes = TagAttributes::createFromCallStackArray($callStackArray, WebCodeTag::TAG);
222                    $renderer->doc .= WebCodeTag::renderExit($tagAttributes, $data);
223                    break;
224            }
225
226            return true;
227        }
228        return false;
229    }
230
231    /**
232     * @param $codes - the array containing the codes
233     * @param $attributes - the attributes of a call (for now the externalResources)
234     * @return void the HTML form code
235     */
236    public function addCodePenButton($codes, $attributes)
237    {
238        // TODO
239        // http://blog.codepen.io/documentation/api/prefill/
240    }
241
242
243}
244