1<?php
2/**
3 * DokuWiki Plugin imagecarousel (Syntax Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  lisps
7 */
8
9// must be run within Dokuwiki
10if (!defined('DOKU_INC')) die();
11
12class syntax_plugin_imagecarousel extends DokuWiki_Syntax_Plugin {
13    /**
14     * @return string Syntax mode type
15     */
16    public function getType() {
17        return 'container';
18    }
19    /**
20     * @return string Paragraph type
21     */
22    public function getPType() {
23        return 'block';
24    }
25    /**
26     * @return int Sort order - Low numbers go before high numbers
27     */
28    public function getSort() {
29        return 104;
30    }
31
32    public function getAllowedTypes() {
33    	return array('substition');
34    }
35
36    /**
37     * Connect lookup pattern to lexer.
38     *
39     * @param string $mode Parser mode
40     */
41    public function connectTo($mode) {
42//         $this->Lexer->addSpecialPattern('<carousel>.*?</carousel>',$mode,'plugin_imagecarousel');
43    	$this->Lexer->addEntryPattern('<carousel.*?>',$mode,'plugin_imagecarousel');
44//     	$this->Lexer->addSpecialPattern("\{\{[^\}]+\}\}",$mode,'media');
45    }
46
47   public function postConnect() {
48   	   $this->Lexer->addPattern('\n {2,}[\*]','plugin_imagecarousel');
49
50       $this->Lexer->addExitPattern('</carousel>','plugin_imagecarousel');
51   }
52
53   protected $first_item = [];
54
55    /**
56     * Handle matches of the imagecarousel syntax
57     *
58     * @param string $match The match of the syntax
59     * @param int    $state The state of the handler
60     * @param int    $pos The position in the document
61     * @param Doku_Handler    $handler The handler
62     * @return array Data for the renderer
63     */
64    public function handle($match, $state, $pos, Doku_Handler $handler){
65        global $ID;
66        $data = array();
67        $data['state'] = $state;
68		switch($state) {
69			case DOKU_LEXER_ENTER:
70				$match = substr($match, 9,-1);  // strip markup
71				$flags = $this->parseFlags($match);
72				$flags['slick'] = json_encode(array_merge(
73						$this->getDefaultFlags(),
74						$flags['slick']
75				));
76				$data['flags'] = $flags;
77				break;
78			case DOKU_LEXER_UNMATCHED:
79				if (trim($match) !== '') {
80					$handler->_addCall('cdata', array($match), $pos);
81				}
82				break;
83			case DOKU_LEXER_EXIT:
84			    $this->first_item[$ID] = false;
85				break;
86			case DOKU_LEXER_MATCHED:
87				if($match === "\n  *") {
88				    if(!isset($this->first_item[$ID]) || !$this->first_item[$ID]) {
89					    $this->first_item[$ID] = true;
90						$data['first_item'] = true;
91					}
92				}
93				break;
94		}
95        return $data;
96    }
97
98    /**
99     * Render xhtml output or metadata
100     *
101     * @param string         $mode      Renderer mode (supported modes: xhtml)
102     * @param Doku_Renderer  $renderer  The renderer
103     * @param array          $data      The data from the handler() function
104     * @return bool If rendering was successful.
105     */
106    public function render($mode, Doku_Renderer $renderer, $data) {
107        if($mode != 'xhtml') return false;
108
109        if($data['state'] === DOKU_LEXER_ENTER) {
110        	$width = ' style="width:'.hsc($data['flags']['self']['width']).'" ';
111        	$renderer->doc .= '<div class="slick '.$data['flags']['self']['position'].'" data-slick=\''.$data['flags']['slick'].'\' '.$width.'>';
112        	$renderer->doc .= '<div>';
113        } else if($data['state'] === DOKU_LEXER_EXIT) {
114        	$renderer->doc .= '</div></div>';
115        } else if($data['state'] === DOKU_LEXER_MATCHED) {
116        	if(!isset($data['first_item'])) {
117        		$renderer->doc .= '</div>';
118        		$renderer->doc .= '<div>';
119        	}
120        }
121        return true;
122    }
123
124    protected function getDefaultFlags() {
125    	$conf = $this->getConf('default');
126    	return $this->parseFlags($conf);
127    }
128
129    protected function parseFlags($confString) {
130    	$confString = explode('&',$confString);
131    	$flags = array(
132    		'slick' => array(),
133    		'self' => array(
134    			'position' => 'center',
135    			'width' => '100%'
136    		),
137    	);
138    	foreach($confString as $flag) {
139
140    		switch($flag) {
141    			case 'center':
142    				$flags['self']['position'] = 'center';
143    				break;
144    			case 'left':
145    				$flags['self']['position'] = 'left';
146    				break;
147    		}
148
149    		$tmp = explode('=',$flag,2);
150    		if(count($tmp) === 2) {
151
152    			switch($tmp[0]) {
153    				case 'width':
154    					$flags['self']['width'] = $tmp[1];
155    					break;
156    				default: //slick parameter
157    					if($tmp[1] === "true") $tmp[1] = true;
158    					else if($tmp[1] === "false") $tmp[1] = false;
159    					else if(is_numeric($tmp[1])) $tmp[1] = intval($tmp[1]);
160    					$flags['slick'][$tmp[0]] = $tmp[1];
161    					break;
162    			}
163
164
165    		}
166    	}
167
168    	return $flags;
169    }
170}
171
172// vim:ts=4:sw=4:et:
173