xref: /plugin/combo/syntax/cite.php (revision 5f891b7e09648e05e78f5882f3fdde1e9df9b0f1)
1<?php
2
3// implementation of
4// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/cite
5
6// must be run within Dokuwiki
7use ComboStrap\LinkUtility;
8use ComboStrap\StringUtility;
9use ComboStrap\Tag;
10use ComboStrap\PluginUtility;
11
12require_once(__DIR__ . '/../class/StringUtility.php');
13
14if (!defined('DOKU_INC')) die();
15
16
17class syntax_plugin_combo_cite extends DokuWiki_Syntax_Plugin
18{
19    const TAG = "cite";
20
21
22    function getType()
23    {
24        return 'container';
25    }
26
27    /**
28     * How Dokuwiki will add P element
29     *
30     * * 'normal' - The plugin can be used inside paragraphs
31     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
32     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
33     *
34     * @see DokuWiki_Syntax_Plugin::getPType()
35     */
36    function getPType()
37    {
38        return 'normal';
39    }
40
41    /**
42     * @return array
43     * Allow which kind of plugin inside
44     *
45     * No one of array('baseonly','container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs')
46     * because we manage self the content and we call self the parser
47     *
48     * Return an array of one or more of the mode types {@link $PARSER_MODES} in Parser.php
49     */
50    function getAllowedTypes()
51    {
52        return array('baseonly', 'container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs');
53    }
54
55    function getSort()
56    {
57        /**
58         * Should be less than the cite syntax plugin
59         **/
60        return 200;
61    }
62
63
64    function connectTo($mode)
65    {
66
67        $pattern = PluginUtility::getContainerTagPattern(self::TAG);
68        $this->Lexer->addEntryPattern($pattern, $mode, PluginUtility::getModeForComponent($this->getPluginComponent()));
69
70    }
71
72
73    function postConnect()
74    {
75
76        $this->Lexer->addExitPattern('</' . syntax_plugin_combo_cite::TAG . '>', PluginUtility::getModeForComponent($this->getPluginComponent()));
77
78    }
79
80    /**
81     *
82     * The handle function goal is to parse the matched syntax through the pattern function
83     * and to return the result for use in the renderer
84     * This result is always cached until the page is modified.
85     * @param string $match
86     * @param int $state
87     * @param int $pos - byte position in the original source file
88     * @param Doku_Handler $handler
89     * @return array|bool
90     * @see DokuWiki_Syntax_Plugin::handle()
91     *
92     */
93    function handle($match, $state, $pos, Doku_Handler $handler)
94    {
95
96        switch ($state) {
97
98            case DOKU_LEXER_ENTER :
99                $tagAttributes = PluginUtility::getTagAttributes($match);
100                $node = new Tag(self::TAG, $tagAttributes, $state, $handler);
101                $parent = "";
102                if ($node->hasParent()) {
103                    $parent = $node->getParent()->getName();
104                }
105                return array(
106                    PluginUtility::STATE => $state,
107                    PluginUtility::ATTRIBUTES => $tagAttributes,
108                    PluginUtility::CONTEXT => $parent);
109
110            case DOKU_LEXER_UNMATCHED :
111                return array(
112                    PluginUtility::STATE => $state,
113                    PluginUtility::PAYLOAD => $match
114                );
115
116            case DOKU_LEXER_EXIT :
117                // Important otherwise we don't get an exit in the render
118                $node = new Tag(self::TAG, array(), $state, $handler);
119                $context = "";
120                if ($node->hasParent()) {
121                    $parent = $node->getParent();
122                    $context = $parent->getName();
123                    if ($context == syntax_plugin_combo_blockquote::TAG) {
124                        $link = $node->getOpeningTag()->getDescendant(syntax_plugin_combo_link::TAG);
125                        if (!empty($link)) {
126                            $ref = $link->getAttribute(LinkUtility::ATTRIBUTE_REF);
127                            if (StringUtility::match($ref, "https:\/\/twitter.com\/[^\/]*\/status\/.*")) {
128                                $context = syntax_plugin_combo_blockquote::TWEET;
129                                $parent->setType($context);
130                                $parent->setContext($context);
131                                $node->getOpeningTag()->setContext($context);
132                            }
133                        }
134                    }
135                }
136                return array(
137                    PluginUtility::STATE => $state,
138                    PluginUtility::CONTEXT => $context);
139
140
141        }
142        return array();
143
144    }
145
146    /**
147     * Render the output
148     * @param string $format
149     * @param Doku_Renderer $renderer
150     * @param array $data - what the function handle() return'ed
151     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
152     * @see DokuWiki_Syntax_Plugin::render()
153     *
154     *
155     */
156    function render($format, Doku_Renderer $renderer, $data)
157    {
158
159        if ($format == 'xhtml') {
160
161            /** @var Doku_Renderer_xhtml $renderer */
162            $state = $data [PluginUtility::STATE];
163            switch ($state) {
164                case DOKU_LEXER_ENTER :
165
166                    $attributes = $data[PluginUtility::ATTRIBUTES];
167                    $context = $data[PluginUtility::CONTEXT];
168                    switch ($context) {
169
170                        case syntax_plugin_combo_blockquote::TAG:
171                            StringUtility::addEolCharacterIfNotPresent($renderer->doc);
172                            $renderer->doc .= "<footer class=\"blockquote-footer\"><cite";
173                            if (sizeof($attributes) > 0) {
174                                $inlineAttributes = PluginUtility::array2HTMLAttributes($attributes);
175                                $renderer->doc .= " $inlineAttributes>";
176                            } else {
177                                $renderer->doc .= '>';
178                            }
179                            break;
180                        case syntax_plugin_combo_blockquote::TWEET:
181                            $renderer->doc .= '</p>';
182                            break;
183                        default:
184                            $renderer->doc .= "<cite";
185                            if (sizeof($attributes) > 0) {
186                                $inlineAttributes = PluginUtility::array2HTMLAttributes($attributes);
187                                $renderer->doc .= " $inlineAttributes";
188                            }
189                            $renderer->doc .= ">";
190                    }
191                    break;
192
193                case DOKU_LEXER_UNMATCHED :
194                    $renderer->doc .= PluginUtility::escape($data[PluginUtility::PAYLOAD]);
195                    break;
196
197                case DOKU_LEXER_EXIT :
198
199                    $context = $data[PluginUtility::CONTEXT];
200                    switch($context){
201                        case syntax_plugin_combo_card::TAG:
202                        case syntax_plugin_combo_blockquote::TAG:
203                            $renderer->doc .= '</cite>';
204                            $renderer->doc .= '</footer>' . DOKU_LF;
205                            break;
206                        case syntax_plugin_combo_blockquote::TWEET:
207                            // There is no element
208                            break;
209                        default:
210                            $renderer->doc .= '</cite>'.DOKU_LF;
211
212                    }
213                    break;
214
215            }
216            return true;
217        }
218
219        // unsupported $mode
220        return false;
221    }
222
223
224}
225
226