1<?php
2/**
3 based on code from http://www.kryogenix.org/code/browser/sorttable/ by Stuart Langridge
4 (distributed under the condisions of MIT licence from http://www.kryogenix.org/code/browser/licence.html)
5 see
6 2007-2016 by oiv (Otto Vainio at otto@valjakko.net)
7 2016-? by vaxquis AKA FyiurAmron (spamove@gmail.com)
8 */
9// must be run within Dokuwiki
10if ( !defined( 'DOKU_INC' ) )
11    die();
12if ( !defined( 'DOKU_PLUGIN' ) )
13    define( 'DOKU_PLUGIN', DOKU_INC.'lib/plugins/' );
14require_once(DOKU_PLUGIN.'syntax.php');
15//
16class syntax_plugin_sortablejs extends DokuWiki_Syntax_Plugin {
17
18    function getType() {
19        return 'container';
20    }
21
22    function getPType() {
23        return 'block';
24    }
25
26    function getSort() {
27        return 371;
28    }
29
30    function getAllowedTypes() {
31        return array( 'container', 'formatting', 'substition' );
32    }
33
34    function connectTo( $mode ) {
35        $this->Lexer->addEntryPattern( '<sortable[^>]*>(?=.*?</sortable>)', $mode, 'plugin_sortablejs' );
36//    $this->Lexer->addEntryPattern('\x3Csortable.*?\x3E',$mode,'plugin_sortablejs');
37//    $this->Lexer->addEntryPattern('<sortable>',$mode,'plugin_sortablejs');
38    }
39
40    function postConnect() {
41        $this->Lexer->addExitPattern( '</sortable>', 'plugin_sortablejs' );
42    }
43
44    function handle( $match, $state, $pos, Doku_Handler $handler ) {
45
46        switch ( $state ) {
47            case DOKU_LEXER_ENTER :
48                $match = substr( $match, 9, -1 );
49                $match = trim( $match );
50                $scl = "";
51                if ( strlen( $match ) > 0 ) {
52                    $scl = $this->__validateOptions( $match );
53                }
54                return array( $state, $scl );
55            case DOKU_LEXER_UNMATCHED :
56//        return p_render('xhtml',p_get_instructions($match),$info);
57                return array( $state, $match );
58            case DOKU_LEXER_EXIT :
59//        return "</div>";
60                return array( $state, "" );
61        }
62        return array();
63    }
64
65    function render( $mode, Doku_Renderer $renderer, $data ) {
66        list($state, $match) = $data;
67        if ( $mode == 'xhtml' ) {
68            switch ( $state ) {
69                case DOKU_LEXER_ENTER :
70                    $renderer->doc .= "<div class=\"sortable$match\">";
71                    break;
72                case DOKU_LEXER_UNMATCHED :
73//          $dbgr = p_render('xhtml',p_get_instructions($match),$info);
74//          $renderer->doc .= p_render('xhtml',p_get_instructions($match),$info);
75//          $renderer->doc .= $match;
76//          $instructions = array_slice(p_get_instructions($match), 1, -1);
77                    $instructions = p_get_instructions( $match );
78                    foreach( $instructions as $instruction ) {
79                        call_user_func_array( array( &$renderer, $instruction[0] ), $instruction[1] );
80                    }
81
82                    break;
83                case DOKU_LEXER_EXIT :
84                    $renderer->doc .= "</div>";
85                    break;
86            }
87            return true;
88        } else if ( $mode == 'odt' ) {
89            switch ( $state ) {
90                case DOKU_LEXER_ENTER :
91                    // In ODT, tables must not be inside a paragraph. Make sure we
92                    // closed any opened paragraph
93                    $renderer->p_close();
94                    break;
95                case DOKU_LEXER_UNMATCHED :
96                    $instructions = array_slice( p_get_instructions( $match ), 1, -1 );
97                    foreach( $instructions as $instruction ) {
98                        call_user_func_array( array( &$renderer, $instruction[0] ), $instruction[1] );
99                    }
100                    break;
101                case DOKU_LEXER_EXIT :
102                    //$renderer->p_open();
103                    // DO NOT re-open the paragraph, it would cause an error if the table is the last content on a page
104                    break;
105            }
106            return true;
107        }
108        return false;
109    }
110
111    function __validateOptions( $opts ) {
112        $oa = explode( " ", $opts );
113        $ret = "";
114        foreach( $oa as $opt ) {
115            list($c, $v) = explode( "=", $opt );
116            if ( $c == "sumrow" ) {
117                $c = $v;
118                $v = "sumrow";
119                if ( $c == "" ) {
120                    $c = "1";
121                }
122            } else if ( $c == "3phase" ) {
123                $v = $c;
124                $c = "";
125            }
126            if ( $v != null ) {
127                $cmpr = $v;
128            } else {
129                if ( preg_match( '/r?\d*/', $c, $matches ) ) {
130                    $cmpr = 'sort';
131                }
132            }
133            switch ( $cmpr ) {
134                case '3phase':
135                    $ret .= " threephase";
136                    break;
137                case 'nosort':
138                    $ret .= " col_".$c."_nosort";
139                    break;
140                case 'numeric':
141                    $ret .= " col_".$c."_numeric";
142                    break;
143                case 'date':
144                    $ret .= " col_".$c."_date";
145                    break;
146                case 'alpha':
147                case 'text':
148                    $ret .= " col_".$c."_alpha";
149                    break;
150                case 'sort':
151                    $ret .= ' sort'.$opt;
152                    break;
153                case 'sumrow':
154                    $ret .= ' sortbottom_'.$c;
155                    //$ret = ' sortbottom' . $ret;
156                    break;
157            }
158        }
159        return $ret;
160    }
161}
162