xref: /plugin/combo/syntax/cell.php (revision 37748cd8654635afbeca80942126742f0f4cc346)
1<?php
2/**
3 * Copyright (c) 2020. 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
13use ComboStrap\ConditionalValue;
14use ComboStrap\Dimension;
15use ComboStrap\PluginUtility;
16use ComboStrap\TagAttributes;
17
18
19require_once(__DIR__ . '/../ComboStrap/PluginUtility.php');
20
21/**
22 * The {@link https://combostrap.com/column column} of a {@link https://combostrap.com/grid grid}
23 *
24 *
25 * Note: The name of the class must follow this pattern ie syntax_plugin_PluginName_ComponentName
26 */
27class syntax_plugin_combo_cell extends DokuWiki_Syntax_Plugin
28{
29
30    const TAG = "cell";
31
32    const WIDTH_ATTRIBUTE = Dimension::WIDTH_KEY;
33    const VERTICAL_ATTRIBUTE = "vertical";
34
35    static function getTags()
36    {
37        return [self::TAG, "col", "column"];
38    }
39
40    /**
41     * Syntax Type.
42     *
43     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
44     * @see DokuWiki_Syntax_Plugin::getType()
45     */
46    function getType()
47    {
48        return 'container';
49    }
50
51    /**
52     * @return array
53     * Allow which kind of plugin inside
54     * All
55     */
56    public function getAllowedTypes()
57    {
58        return array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs');
59    }
60
61    public function accepts($mode)
62    {
63
64        /**
65         * header mode is disable to take over
66         * and replace it with {@link syntax_plugin_combo_heading}
67         */
68        if ($mode == "header") {
69            return false;
70        }
71
72
73        return syntax_plugin_combo_preformatted::disablePreformatted($mode);
74
75    }
76
77    /**
78     * How Dokuwiki will add P element
79     *
80     *  * 'normal' - The plugin can be used inside paragraphs
81     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
82     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
83     *
84     * @see DokuWiki_Syntax_Plugin::getPType()
85     */
86    function getPType()
87    {
88        return 'stack';
89    }
90
91    /**
92     * @see Doku_Parser_Mode::getSort()
93     *
94     * the mode with the lowest sort number will win out
95     * the container (parent) must then have a lower number than the child
96     */
97    function getSort()
98    {
99        return 100;
100    }
101
102    /**
103     * Create a pattern that will called this plugin
104     *
105     * @param string $mode
106     * @see Doku_Parser_Mode::connectTo()
107     */
108    function connectTo($mode)
109    {
110
111        // A cell can be anywhere
112        foreach (self::getTags() as $tag) {
113            $pattern = PluginUtility::getContainerTagPattern($tag);
114            $this->Lexer->addEntryPattern($pattern, $mode, PluginUtility::getModeFromTag($this->getPluginComponent()));
115        }
116
117
118    }
119
120    public function postConnect()
121    {
122
123        foreach (self::getTags() as $tag) {
124            $this->Lexer->addExitPattern('</' . $tag . '>', PluginUtility::getModeFromTag($this->getPluginComponent()));
125        }
126
127    }
128
129    /**
130     *
131     * The handle function goal is to parse the matched syntax through the pattern function
132     * and to return the result for use in the renderer
133     * This result is always cached until the page is modified.
134     * @param string $match
135     * @param int $state
136     * @param int $pos
137     * @param Doku_Handler $handler
138     * @return array|bool
139     * @see DokuWiki_Syntax_Plugin::handle()
140     *
141     */
142    function handle($match, $state, $pos, Doku_Handler $handler)
143    {
144
145        switch ($state) {
146
147            case DOKU_LEXER_ENTER:
148
149                $attributes = TagAttributes::createFromTagMatch($match)->toCallStackArray();
150                return array(
151                    PluginUtility::STATE => $state,
152                    PluginUtility::ATTRIBUTES => $attributes);
153
154            case DOKU_LEXER_UNMATCHED:
155                return PluginUtility::handleAndReturnUnmatchedData(self::TAG, $match, $handler);
156
157            case DOKU_LEXER_EXIT :
158
159                return array(
160                    PluginUtility::STATE => $state
161                );
162
163
164        }
165
166        return array();
167
168    }
169
170    /**
171     * Render the output
172     * @param string $format
173     * @param Doku_Renderer $renderer
174     * @param array $data - what the function handle() return'ed
175     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
176     * @see DokuWiki_Syntax_Plugin::render()
177     *
178     *
179     */
180    function render($format, Doku_Renderer $renderer, $data)
181    {
182
183        if ($format == 'xhtml') {
184
185            /** @var Doku_Renderer_xhtml $renderer */
186            $state = $data[PluginUtility::STATE];
187            switch ($state) {
188
189                case DOKU_LEXER_ENTER :
190
191                    PluginUtility::getSnippetManager()->attachCssSnippetForBar(self::TAG);
192                    $callStackArray = $data[PluginUtility::ATTRIBUTES];
193                    $attributes = TagAttributes::createFromCallStackArray($callStackArray, self::TAG);
194                    $attributes->addClassName("col");
195                    if ($attributes->hasComponentAttribute(self::VERTICAL_ATTRIBUTE)) {
196                        $value = $attributes->getValue(self::VERTICAL_ATTRIBUTE);
197                        if ($value == "center") {
198                            //$attributes->addClassName("d-inline-flex");
199                            $attributes->addClassName("align-self-center");
200                        }
201                    }
202                    if ($attributes->hasComponentAttribute(syntax_plugin_combo_cell::WIDTH_ATTRIBUTE)) {
203                        $sizeValues = $attributes->getValuesAndRemove(syntax_plugin_combo_cell::WIDTH_ATTRIBUTE);
204                        foreach ($sizeValues as $sizeValue) {
205                            $conditionalValue = ConditionalValue::createFrom($sizeValue);
206                            if ($conditionalValue->getBreakpoint() == "xs") {
207                                $attributes->addClassName("col-" . $conditionalValue->getValue());
208                            } else {
209                                if ($conditionalValue->getBreakpoint() != null) {
210                                    $attributes->addClassName("col-$sizeValue");
211                                } else {
212                                    /**
213                                     * No breakpoint given
214                                     * If this is a number between 1 and 12,
215                                     * we take the assumption that this is a ratio
216                                     * otherwise, this a width in CSS length
217                                     */
218                                    if ($sizeValue >= 1 && $sizeValue <= syntax_plugin_combo_row::GRID_TOTAL_COLUMNS) {
219                                        $attributes->addClassName("col-$sizeValue");
220                                    } else {
221                                        $attributes->addComponentAttributeValue(Dimension::WIDTH_KEY, $sizeValue);
222                                    }
223                                }
224                            }
225                        }
226                    }
227                    $renderer->doc .= $attributes->toHtmlEnterTag("div") . DOKU_LF;
228                    break;
229
230                case DOKU_LEXER_UNMATCHED :
231
232                    $renderer->doc .= PluginUtility::renderUnmatched($data);
233                    break;
234
235                case DOKU_LEXER_EXIT :
236
237                    $renderer->doc .= '</div>' . DOKU_LF;
238                    break;
239            }
240            return true;
241        }
242        return false;
243    }
244
245
246}
247