xref: /plugin/combo/syntax/cite.php (revision 32b85071e019dd3646a67c17fac4051338e495eb)
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 PluginUtility::handleAndReturnUnmatchedData(self::TAG, $match, $handler);
112
113            case DOKU_LEXER_EXIT :
114                // Important otherwise we don't get an exit in the render
115                $node = new Tag(self::TAG, array(), $state, $handler);
116                $context = "";
117                if ($node->hasParent()) {
118                    $parent = $node->getParent();
119                    $context = $parent->getName();
120                    if ($context == syntax_plugin_combo_blockquote::TAG) {
121                        $link = $node->getOpeningTag()->getDescendant(syntax_plugin_combo_link::TAG);
122                        if (!empty($link)) {
123                            $ref = $link->getAttribute(LinkUtility::ATTRIBUTE_REF);
124                            if (StringUtility::match($ref, "https:\/\/twitter.com\/[^\/]*\/status\/.*")) {
125                                $context = syntax_plugin_combo_blockquote::TWEET;
126                                $parent->setType($context);
127                                $parent->setContext($context);
128                                $node->getOpeningTag()->setContext($context);
129                            }
130                        }
131                    }
132                }
133                return array(
134                    PluginUtility::STATE => $state,
135                    PluginUtility::CONTEXT => $context);
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
156        if ($format == 'xhtml') {
157
158            /** @var Doku_Renderer_xhtml $renderer */
159            $state = $data [PluginUtility::STATE];
160            switch ($state) {
161                case DOKU_LEXER_ENTER :
162
163                    $attributes = $data[PluginUtility::ATTRIBUTES];
164                    $context = $data[PluginUtility::CONTEXT];
165                    switch ($context) {
166
167                        case syntax_plugin_combo_blockquote::TAG:
168                            StringUtility::addEolCharacterIfNotPresent($renderer->doc);
169                            $renderer->doc .= "<footer class=\"blockquote-footer\"><cite";
170                            if (sizeof($attributes) > 0) {
171                                $inlineAttributes = PluginUtility::array2HTMLAttributes($attributes);
172                                $renderer->doc .= " $inlineAttributes>";
173                            } else {
174                                $renderer->doc .= '>';
175                            }
176                            break;
177                        case syntax_plugin_combo_blockquote::TWEET:
178                            $renderer->doc .= '</p>';
179                            break;
180                        default:
181                            $renderer->doc .= "<cite";
182                            if (sizeof($attributes) > 0) {
183                                $inlineAttributes = PluginUtility::array2HTMLAttributes($attributes);
184                                $renderer->doc .= " $inlineAttributes";
185                            }
186                            $renderer->doc .= ">";
187                    }
188                    break;
189
190                case DOKU_LEXER_UNMATCHED :
191                    $renderer->doc .= PluginUtility::renderUnmatched($data);
192                    break;
193
194                case DOKU_LEXER_EXIT :
195
196                    $context = $data[PluginUtility::CONTEXT];
197                    switch ($context) {
198                        case syntax_plugin_combo_card::TAG:
199                        case syntax_plugin_combo_blockquote::TAG:
200                            $renderer->doc .= '</cite>';
201                            $renderer->doc .= '</footer>' . DOKU_LF;
202                            break;
203                        case syntax_plugin_combo_blockquote::TWEET:
204                            // There is no element
205                            break;
206                        default:
207                            $renderer->doc .= '</cite>' . DOKU_LF;
208
209                    }
210                    break;
211
212            }
213            return true;
214        }
215
216        // unsupported $mode
217        return false;
218    }
219
220
221}
222
223