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