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