tra('MediaWiki Table'), 'documentation' => 'PluginMWTable', 'description' => tra('Display a table using MediaWiki syntax'), 'prefs' => [ 'wikiplugin_mwtable' ], 'body' => tra('URL'), 'validate' => 'all', 'iconname' => 'table', 'introduced' => 3, 'tags' => ['experimental'], 'params' => [ 'fancy' => [ 'safe' => true, 'required' => false, 'name' => tra('Fancy'), 'description' => tr('Set to true to apply additional formatting to the table (header style, odd/even rows, etc.). Takes precedence over the %0wiki_classes%1 parameter.', '', ''), 'since' => '3.0', 'default' => 'false', 'filter' => 'word', 'options' => [ ['text' => '', 'value' => ''], ['text' => tra('True'), 'value' => 'true'], ['text' => tra('False'), 'value' => 'false'] ] ], 'wiki_classes' => [ 'safe' => true, 'required' => false, 'name' => tra('Wiki Classes'), 'description' => tra('Determines whether wiki style classes will be used for the table and cells (used by default)'), 'since' => '3.0', 'default' => 'true', 'filter' => 'word', 'options' => [ ['text' => '', 'value' => ''], ['text' => tra('True'), 'value' => 'true'], ['text' => tra('False'), 'value' => 'false'] ] ] ] ]; } function wikiplugin_mwtable($data, $params) { global $tikilib; // Parse the parameters extract($params, EXTR_SKIP); if (isset($fancy) and $fancy == "true") { $fancy = true; } else { $fancy = false; } if (isset($wiki_classes) and $wiki_classes == "false") { $wiki_classes = false; } else { $wiki_classes = true; } // set class constants $default_class_table = "normal"; $default_class_heading = ""; $default_class_td_odd = ""; $default_class_td_odd = ""; if ($fancy) { $default_class_table = "normal"; $default_class_heading = "heading"; $default_class_td_odd = "odd"; $default_class_td_even = "even"; } elseif ($wiki_classes) { $default_class_table = "wikitable"; $default_class_td_odd = "wikicell"; $default_class_td_even = "wikicell"; } // soe = start-of-element; eoe = end-of-element // set the start position $soe = 0; // : prefix = start-of-string, suffix = "\n" $suffix = "\n"; $eoe = strpos($data, $suffix); // we only have attributes $element = substr($data, $soe, $eoe - strlen($suffix)); $attributes = _get_attributes($element); _check_class_attribute($attributes, $default_class_table); $wret .= _output_tag_with_attributes("table", $attributes, true); // move soe - skip terminating suffix $soe = $eoe + strlen($suffix); //
: end (of start tag) // \n"; // move soe - skip terminating suffix $soe = $eoe + strlen($suffix); } // : prefix = "?", suffix = "!" or "|-" $prefix = "?"; $suffix = "!"; if (substr($data, $soe, strlen($prefix)) == $prefix) { // the end of the column data is the start of the headings // or the start of the rows $pos_headings = strpos($data, "!", $soe); $pos_rows = strpos($data, "|-", $soe); if ($pos_headings) { //assume if headings present they precede any row $eoe = $pos_headings; } else { // assume element delimited by first row $suffix = "|-"; $eoe = $pos_rows; } $element = substr($data, $soe + strlen($prefix), $eoe - $soe - strlen($prefix) - strlen($suffix)); // convert "??" to "\n?" to simplify splitting $element = str_replace("??", "\n?", $element); $columns = explode("?", $element); foreach ($columns as $column) { // we only have attributes $attributes = _get_attributes($column); $wret .= _output_tag_with_attributes("col", $attributes, true, true); } // move soe - keep terminating string $soe = $eoe; } // : end // \n"; foreach ($columns as $column) { // each column can have attributes and/or text if (strpos($column, "|")) { list($attribs, $text) = explode("|", $column, 2); $attributes = _get_attributes($attribs); _check_class_attribute($attributes, $default_class_headings); $wret .= _output_tag_with_attributes("th", $attributes); $wret .= trim($text); } else { // only one part so use as heading $wret .= "\n"; } $wret .= "\n"; // move soe - keep terminating "|-" $soe = $eoe; } // : prefix = "|-", suffix = "|-" or end-of-data // skip over prefix for first row $prefix = "|-"; $rows = explode($prefix, substr($data, $soe + strlen($prefix))); $row_is_odd = true; foreach ($rows as $row) { // each row if ($row_is_odd) { $default_class_td = $default_class_td_odd; } else { $default_class_td = $default_class_td_even; } $row_is_odd = ! $row_is_odd; // the end of row attributes is the end of the line/start of cell $suffix = "\n|"; $eoe = strpos($row, $suffix); $attribs = substr($row, 0, $eoe - strlen($suffix)); $attributes = _get_attributes($attribs); $wret .= _output_tag_with_attributes("tr", $attributes, true); // extract just the data for the cells - skip prefix of first cell $soe = $eoe + strlen($suffix); $row_cells = substr($row, $soe); // the cells $prefix = "\n|"; // convert "||" to "\n|" to simplify splitting $row_cells = str_replace("||", $prefix, $row_cells); // get cells - skip over prefix of first cell $cells = explode($prefix, $row_cells); foreach ($cells as $cell) { if (strpos($cell, "|")) { list($attribs, $text) = explode("|", $cell, 2); $attributes = _get_attributes($attribs); } else { // only one part so use as text $attributes = []; $text = $cell; } _check_class_attribute($attributes, $default_class_td); $wret .= _output_tag_with_attributes("td", $attributes); $wret .= trim($text); // end of cell $wret .= "\n"; } // end the row $wret .= "\n"; } // End the table $wret .= "
: prefix = "|+", suffix = "\n" $prefix = "|+"; $suffix = "\n"; if (substr($data, $soe, strlen($prefix)) == $prefix) { $eoe = strpos($data, $suffix, $soe); $element = substr($data, $soe + strlen($prefix), $eoe - $soe - strlen($prefix) - strlen($suffix)); if (strpos($element, "|")) { // attributes present list($attribs, $text) = explode("|", $element, 2); $attributes = _get_attributes($attribs); $wret .= _output_tag_with_attributes("caption", $attributes, true); $wret .= trim($text); } else { $wret .= "" . trim($element); } $wret .= ": end //
: prefix = "!", suffix = "|-" $prefix = "!"; $suffix = "|-"; if (substr($data, $soe, strlen($prefix)) == $prefix) { // the end of the heading data is the start of the first row $eoe = strpos($data, "|-", $soe); $element = substr($data, $soe + strlen($prefix), $eoe - $soe - strlen($prefix) - strlen($suffix)); // convert "!!" to "\n!" to simplify splitting $element = str_replace("!!", "\n!", $element); $columns = explode("!", $element); $wret .= "
" . trim($column); } $wret .= "
: end //
\n"; return $wret; } // We need a function to parse attributes as wiki syntax rules do // funny things to the data. // % needs to be enclosed in double-quotes to not be a dynamic variable // double-quotes have become " which is no good for an html attribute // // Return an associative array where value has had any delimiters removed. function _get_attributes($string) { $attributes = []; $cur_pos = 0; while ($cur_pos < strlen($string)) { // identify key if (preg_match("/\s*(\w+)=/", $string, $matches, PREG_OFFSET_CAPTURE, $cur_pos)) { $cur_pos += strlen($matches[0][0]); // skip whole pattern $key = $matches[1][0]; // just store key // identify value: // use # as start/end character inclusion of / in value if (preg_match("#([(")\"'\w:;%-/\.]+)(?=\s|\Z)#", $string, $matches, PREG_OFFSET_CAPTURE, $cur_pos)) { $cur_pos += strlen($matches[0][0]); // skip whole pattern $value = $matches[1][0]; // just store value // remove delimiters (quote or double-quote if present) $value = str_replace("'", "", $value); $value = str_replace(""", "", $value); } else { $value = substr($string, $cur_pos); $cur_pos = strlen($string); } $attributes[$key] = $value; } else { $cur_pos = strlen($string); } } return $attributes; } // If terminate_tag==False return in the form // If terminate_tag==True return in the form // The latter is only applicable to a few tags like . function _output_tag_with_attributes($tag, $attributes, $newline = false, $terminate_tag = false) { $output = "<" . $tag; if (count($attributes)) { foreach ($attributes as $key => $value) { $output .= " " . $key . "=\"" . $value . "\""; } } if ($terminate_tag) { $output .= "/"; } $output .= ">"; if ($newline) { $output .= "\n"; } return $output; } // Check the class element. // if $add==True add default class to any existing class else replace function _check_class_attribute(&$attributes, $default_class = "", $add = true) { // if no default class then nothing to do if (strlen($default_class) == 0) { return; } $class = $default_class; if ($add and (array_key_exists("class", $attributes))) { $class .= " " . $attributes["class"]; } $attributes["class"] = $class; }