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 12// must be run within Dokuwiki 13if ( !defined( 'DOKU_INC' ) ) 14 die(); 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 } 37 38 function postConnect() { 39 $this->Lexer->addExitPattern( '</sortable>', 'plugin_sortablejs' ); 40 } 41 42 function handle( $match, $state, $pos, Doku_Handler $handler ) { 43 44 switch ( $state ) { 45 case DOKU_LEXER_ENTER : 46 $match = substr( $match, 9, -1 ); 47 $match = trim( $match ); 48 $scl = ""; 49 if ( strlen( $match ) > 0 ) { 50 $scl = $this->__validateOptions( $match ); 51 } 52 return array( $state, $scl ); 53 case DOKU_LEXER_UNMATCHED : 54 return array( $state, $match ); 55 case DOKU_LEXER_EXIT : 56 return array( $state, "" ); 57 } 58 return array(); 59 } 60 61 function render( $mode, Doku_Renderer $renderer, $data ) { 62 list($state, $match) = $data; 63 if ( $mode == 'xhtml' ) { 64 switch ( $state ) { 65 case DOKU_LEXER_ENTER : 66 $renderer->doc .= "<div class=\"sortable$match\">"; 67 break; 68 case DOKU_LEXER_UNMATCHED : 69 $instructions = p_get_instructions( $match ); 70 foreach( $instructions as $instruction ) { 71 call_user_func_array( array( &$renderer, $instruction[0] ), $instruction[1] ); 72 } 73 74 break; 75 case DOKU_LEXER_EXIT : 76 $renderer->doc .= "</div>"; 77 break; 78 } 79 return true; 80 } else if ( $mode == 'odt' ) { 81 switch ( $state ) { 82 case DOKU_LEXER_ENTER : 83 // In ODT, tables must not be inside a paragraph. Make sure we 84 // closed any opened paragraph 85 $renderer->p_close(); 86 break; 87 case DOKU_LEXER_UNMATCHED : 88 $instructions = array_slice( p_get_instructions( $match ), 1, -1 ); 89 foreach( $instructions as $instruction ) { 90 call_user_func_array( array( &$renderer, $instruction[0] ), $instruction[1] ); 91 } 92 break; 93 case DOKU_LEXER_EXIT : 94 //$renderer->p_open(); 95 // DO NOT re-open the paragraph, it would cause an error if the table is the last content on a page 96 break; 97 } 98 return true; 99 } 100 return false; 101 } 102 103 function __validateOptions( $opts ) { 104 if ( empty( $opts ) ) { 105 return ""; 106 } 107 $ret = ""; 108 $oa = explode( " ", $opts ); 109 foreach( $oa as $opt ) { 110 $explodedOption = explode( "=", $opt ); 111 $c = $explodedOption[0]; 112 $v = $explodedOption[1] ?? null; 113 if ( $c == "sumrow" ) { 114 $c = $v; 115 $v = "sumrow"; 116 if ( $c == "" ) { 117 $c = "1"; 118 } 119 } else if ( $c == "3phase" ) { 120 $v = $c; 121 $c = ""; 122 } 123 if ( $v != null ) { 124 $cmpr = $v; 125 } else { 126 if ( preg_match( '/r?\d*/', $c, $matches ) ) { 127 $cmpr = 'sort'; 128 } 129 } 130 switch ( $cmpr ) { 131 case '3phase': 132 $ret .= " threephase"; 133 break; 134 case 'nosort': 135 $ret .= " col_".$c."_nosort"; 136 break; 137 case 'numeric': 138 $ret .= " col_".$c."_numeric"; 139 break; 140 case 'date': 141 $ret .= " col_".$c."_date"; 142 break; 143 case 'alpha': 144 case 'text': 145 $ret .= " col_".$c."_alpha"; 146 break; 147 case 'sort': 148 $ret .= ' sort'.$opt; 149 break; 150 case 'sumrow': 151 $ret .= ' sortbottom_'.$c; 152 break; 153 } 154 } 155 return $ret; 156 } 157} 158