1<?php
2
3
4// must be run within Dokuwiki
5use ComboStrap\CallStack;
6use ComboStrap\Dimension;
7use ComboStrap\PluginUtility;
8use ComboStrap\TagAttributes;
9use ComboStrap\TextAlign;
10
11if (!defined('DOKU_INC')) die();
12
13/**
14 * Class syntax_plugin_combo_text
15 * A text block that permits to style
16 * paragraph at once
17 *
18 * The output will be a series of {@link syntax_plugin_combo_para paragraph}
19 * with the same properties
20 *
21 * It permits to have several paragraph
22 */
23class syntax_plugin_combo_text extends DokuWiki_Syntax_Plugin
24{
25
26    const TAG = "text";
27    const TAGS = ["typo", self::TAG];
28
29    /**
30     * Syntax Type.
31     *
32     * Needs to return one of the mode types defined in {@link $PARSER_MODES} in parser.php
33     * @see DokuWiki_Syntax_Plugin::getType()
34     */
35    function getType()
36    {
37        return 'paragraphs';
38    }
39
40    /**
41     * How Dokuwiki will add P element
42     *
43     *  * 'normal' - The plugin can be used inside paragraphs
44     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
45     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
46     *
47     * @see DokuWiki_Syntax_Plugin::getPType()
48     */
49    function getPType()
50    {
51        return 'stack';
52    }
53
54    /**
55     * @return array
56     * Allow which kind of plugin inside
57     *
58     * No one of array('baseonly','container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs')
59     * because we manage self the content and we call self the parser
60     *
61     * Return an array of one or more of the mode types {@link $PARSER_MODES} in Parser.php
62     */
63    function getAllowedTypes()
64    {
65        return array('formatting', 'substition', 'paragraphs');
66    }
67
68    public function accepts($mode)
69    {
70
71        return syntax_plugin_combo_preformatted::disablePreformatted($mode);
72
73    }
74
75
76    function getSort()
77    {
78        return 201;
79    }
80
81
82    function connectTo($mode)
83    {
84
85        foreach (self::TAGS as $tag) {
86            $pattern = PluginUtility::getContainerTagPattern($tag);
87            $this->Lexer->addEntryPattern($pattern, $mode, PluginUtility::getModeFromTag($this->getPluginComponent()));
88        }
89    }
90
91
92    function postConnect()
93    {
94        foreach (self::TAGS as $tag) {
95            $this->Lexer->addExitPattern('</' . $tag . '>', PluginUtility::getModeFromTag($this->getPluginComponent()));
96        }
97
98    }
99
100    function handle($match, $state, $pos, Doku_Handler $handler)
101    {
102
103        switch ($state) {
104
105            case DOKU_LEXER_ENTER :
106                $attributes = TagAttributes::createFromTagMatch($match);
107                $callStackArray = $attributes->toCallStackArray();
108
109                return array(
110                    PluginUtility::STATE => $state,
111                    PluginUtility::ATTRIBUTES => $callStackArray
112                );
113
114            case DOKU_LEXER_UNMATCHED :
115                return PluginUtility::handleAndReturnUnmatchedData(self::TAG, $match, $handler);
116
117            case DOKU_LEXER_EXIT :
118                /**
119                 * Transform all paragraphs
120                 * with the type as class
121                 */
122                $callStack = CallStack::createFromHandler($handler);
123                $openingCall = $callStack->moveToPreviousCorrespondingOpeningCall();
124                $attributes = $openingCall->getAttributes();
125                // if there is no EOL, we add one to create at minimal a paragraph
126                $callStack->insertEolIfNextCallIsNotEolOrBlock();
127                $callStack->processEolToEndStack($attributes);
128
129                /**
130                 * Check and add a scroll toggle if the
131                 * text is constrained by height
132                 */
133                Dimension::addScrollToggleOnClickIfNoControl($callStack);
134
135                return array(PluginUtility::STATE => $state);
136
137
138        }
139        return array();
140
141    }
142
143    /**
144     * Render the output
145     * @param string $format
146     * @param Doku_Renderer $renderer
147     * @param array $data - what the function handle() return'ed
148     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
149     * @see DokuWiki_Syntax_Plugin::render()
150     *
151     *
152     */
153    function render($format, Doku_Renderer $renderer, $data)
154    {
155        if ($format == 'xhtml') {
156
157            /** @var Doku_Renderer_xhtml $renderer */
158            $state = $data[PluginUtility::STATE];
159            switch ($state) {
160                case DOKU_LEXER_EXIT :
161                case DOKU_LEXER_ENTER :
162                    /**
163                     * The {@link DOKU_LEXER_EXIT} of the {@link syntax_plugin_combo_text::handle()}
164                     * has already created in the callstack the {@link syntax_plugin_combo_para} call
165                     */
166                    $renderer->doc .= "";
167                    break;
168                case DOKU_LEXER_UNMATCHED :
169                    $renderer->doc .= PluginUtility::renderUnmatched($data);
170                    break;
171            }
172            return true;
173        }
174
175        // unsupported $mode
176        return false;
177    }
178
179
180}
181
182