1<?php
2/**
3 * DokuWiki Syntax Plugin Web Component.
4 *
5 */
6if (!defined('DOKU_INC')) {
7    die();
8}
9
10require_once(__DIR__ . '/../webcomponent.php');
11
12/**
13 * All DokuWiki plugins to extend the parser/rendering mechanism
14 * need to inherit from this class
15 *
16 * The name of the class must follow a pattern (don't change it)
17 * ie:
18 *    syntax_plugin_PluginName_ComponentName
19 *
20 * An attempt to add markdown header
21 *
22 */
23class syntax_plugin_webcomponent_heading extends DokuWiki_Syntax_Plugin
24{
25
26
27    /**
28     * Syntax Type.
29     *
30     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
31     * @see DokuWiki_Syntax_Plugin::getType()
32     */
33    function getType()
34    {
35        return 'container';
36    }
37
38    /**
39     * @return array
40     * Allow which kind of plugin inside
41     * All
42     */
43    public function getAllowedTypes()
44    {
45        // array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs');
46        return array();
47    }
48
49    /**
50     * How Dokuwiki will add P element
51     *
52     * * 'normal' - The plugin can be used inside paragraphs
53     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
54     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
55     *
56     * @see DokuWiki_Syntax_Plugin::getPType()
57     */
58    function getPType()
59    {
60        return 'block';
61    }
62
63    /**
64     * @see Doku_Parser_Mode::getSort()
65     *
66     * the mode with the lowest sort number will win out
67     * the container (parent) must then have a lower number than the child
68     */
69    function getSort()
70    {
71        // same as parser.php#Doku_Parser_Mode_header
72        return 50;
73    }
74
75    /**
76     * Create a pattern that will called this plugin
77     *
78     * @see Doku_Parser_Mode::connectTo() to see the implemented function interface
79     * @see Doku_Parser_Mode_header::connectTo() to see where the code is borrowed for.
80     *
81     * @param string $mode
82     */
83    function connectTo($mode)
84    {
85
86        $headerCharacter = self::getHeadingCharacter();
87        $pattern = '^' . $headerCharacter . '[^'.DOKU_LF.']+$';
88        $this->Lexer->addSpecialPattern($pattern, $mode, 'plugin_' . webcomponent::PLUGIN_NAME . '_' . $this->getPluginComponent());
89
90    }
91
92    public function postConnect()
93    {
94
95        // None
96
97    }
98
99    /**
100     *
101     * The handle function goal is to parse the matched syntax through the pattern function
102     * and to return the result for use in the renderer
103     * This result is always cached until the page is modified.
104     * @see DokuWiki_Syntax_Plugin::handle()
105     * @see Doku_Handler::header() to see the original Dokuwiki code
106     *
107     * @param string $match
108     * @param int $state
109     * @param int $pos
110     * @param Doku_Handler $handler
111     * @return array|bool
112     *
113     *
114     */
115    function handle($match, $state, $pos, Doku_Handler $handler)
116    {
117
118        switch ($state) {
119
120            case DOKU_LEXER_SPECIAL :
121                // Must return $text, $level, $pos
122                // get level and title
123                $title = trim($match);
124                $level = strspn($title, self::getHeadingCharacter());
125                if ($level < 1) $level = 1;
126                $title = trim($title, self::getHeadingCharacter());
127                $title = trim($title);
128
129                /* seems to manage the renderer call */
130                if ($handler->status['section']) $handler->_addCall('section_close', array(), $pos);
131                $handler->_addCall('header', array($title, $level, $pos), $pos);
132                $handler->_addCall('section_open', array($level), $pos);
133                $handler->status['section'] = true;
134
135                return array($state, array($title, $level, $pos));
136
137        }
138        return array();
139
140    }
141
142    /**
143     * Call the underlying dokuwiki renderer
144     *
145     * @see DokuWiki_Syntax_Plugin::render() for the interface method
146     * @see Doku_Renderer_xhtml::header() for the original method
147     *
148     * @param string $mode
149     * @param Doku_Renderer $renderer
150     * @param array $data - what the function handle() return'ed
151     * @return bool
152     */
153    function render($mode, Doku_Renderer $renderer, $data)
154    {
155
156        /** @var Doku_Renderer_xhtml $renderer */
157//        list($state, $parameters) = $data;
158//        switch ($state) {
159//
160//            case DOKU_LEXER_SPECIAL :
161//                list($title, $level, $pos) = $parameters;
162//                $renderer->header($title, $level, $pos);
163//                break;
164//
165//        }
166//        return true;
167
168
169    }
170
171
172    public static function getHeadingCharacter()
173    {
174        return '#';
175    }
176
177}
178