#||
||
Compatible with: !!(green)**R6.1**!!
Current version: **0.3** (beta)
Credits: http://docs.wikkawiki.org/FormatterCSV
|{{toc numerate=1}} ||
||#
This formatter converts inline CSV data into a table.
===Features===
* supports both ##comma## (default) and ##semicolon## as separator
* rows of the table alternate background color
* column alignment: ##\##left##\##, ##/##right##/##, ##""|""##center##""|""## or default
* table headers/footers using wiki style ##""==""##heading markers##""==""##
* add comments in between data by starting a line with (##""#""##); blank lines are ignored
* cells can be surrounded in double quotes (##"##); text in quotes is preserved e.g., whitespace, no splitting on the separator
* it is possible to escape a separator with a backslash (##\##), that should appear in text
* wiki links in cell text are linked to their internal wiki pages
===Usage===
Call via ##(csv [delim=[comma|semicolon])##
##""%%(csv delim="semicolon") source%%""##
((source:master/community/formatter/highlight/csv.php formatter/highlight/csv.php))
``(php)
<?php
/*
converts inline csv data into a table
%%(csv
[delim="comma|semicolon"]
)
content
%%
https://wackowiki.org/doc/Dev/PatchesHacks/CSV
*/
$options['delim'] ??= 'comma';
$delim = match($options['delim']) {
'semicolon' => ';',
default => ',',
};
$blanks = 0;
$csv_lines = preg_split('/[\n]/', $text);
// asserts what precedes the ; is not a backslash \\\\, doesn't account for \\; (escaped backslash semicolon)
// https://stackoverflow.com/questions/40479546/how-to-split-on-white-spaces-not-between-quotes
// split on delimiter but not between quotes
$regex_split = '/(?<!\\\\)' . $delim . '(?=(?:[^\"]*([\"])[^\"]*\\1)*[^\"]*$)/';
$regex_escaped = '/\\\\' . $delim . '/';
$tpl->enter('r_');
foreach ($csv_lines as $i => $line)
{
if (preg_match('/^#|^\s*$/', $line))
{
$blanks++;
continue;
}
$tpl->commit = true; // alternation hack
$tpl->enter('c_');
foreach (preg_split($regex_split, $line) as $r => $field)
{
$tpl->commit = true; // alternation hack
if ($i == $blanks)
{
$class[$r] = ''; // 'padding: 1px 10px 1px 10px; ';
}
if (preg_match('/^\"?\s*==(.*)==\s*\"?$/', $field, $header))
{
$title[$r] = $header[1];
if (preg_match('/([\/\\\\|])(.*)\\1$/', $title[$r], $align))
{
$class[$r] .= match($align[1]) {
'/' => 't-right',
'\\' => 't-left',
'|' => 't-center',
};
$title[$r] = $align[2];
}
$tpl->h_class = $class[$r];
$tpl->h_title = $title[$r];
continue;
}
// if a cell is blank, echo NBSP
if (preg_match('/^\s*$/', $field))
{
$tpl->t_class = $class[$r];
$tpl->t_cell = "\u{00A0}";
continue;
}
// extract the cell out of it's quotes
else if (preg_match('/^\s*(\"?)(.*?)\\1\s*$/', $field, $matches))
{
if ($matches[1] == '"')
{
#$style[$r] = 'white-space: pre; ' . $style[$r];
$cell = $matches[2];
}
else
{
$cell = preg_replace($regex_escaped, $delim, $matches[2]);
}
// [[wiki link]]
if (preg_match_all('/\[\[([[:alnum:]]+)\]\]/', $cell, $all_links))
{
$linked = $cell;
foreach ($all_links[1] as $camel_link)
{
$linked = preg_replace('/\[\[' . $camel_link . '\]\]/', $this->link($camel_link), $linked);
}
}
// [[url label]]
else if (preg_match_all('/\[\[(.*?)\]\]/', $cell, $all_links))
{
$linked = $cell;
foreach ($all_links[1] as $url_link)
{
if(preg_match('/^(\S+)(\s+(.+))?$/us', $url_link, $matches))
{
$url = $matches[1] ?? '';
$text = $matches[3] ?? '';
$linked = preg_replace('#\[\[' . $matches[0] . '\]\]#', $this->link($url, '', $text), $linked);
}
}
}
else
{
$linked = Ut::html($cell);
}
$tpl->t_class = $class[$r];
$tpl->t_cell = $linked;
continue;
}
$tpl->t_class = $class[$r];
$tpl->t_cell = 'ERROR!';
}
$tpl->leave(); // c_
}
$tpl->leave(); // r_
``
((source:master/community/formatter/highlight/template/csv.tpl formatter/highlight/template/csv.tpl))
%%
[ === main === ]
<ignore>
<!--notypo-->
<table class="usertable">
<tbody>
[= r _ =
[ ' commit | void ' ]
<tr>
[= c _ =
[ ' commit | void ' ]
[= h _ =
<th class="[ ' class ' ]">[ ' title | e ' ]</th>
=]
[= t _ =
<td class="[ ' class ' ]">[ ' cell ' ]</td>
=]
=]
</tr>
=]
</tbody>
</table>
<!--/notypo-->
</ignore>
%%
====local usage of repository====
Symlink the formatter from community folder in the **src/formatter/highlight** folder and the corresponding template in the **src/formatter/highlight/template** folder in your repo.
%%
ln -s ../../../community/formatter/highlight/csv.php csv.php
ln -s ../../../../community/formatter/highlight/template/csv.tpl csv.tpl
%%
===Example===
##""%%(csv delim="semicolon")
; ==/First Name/==; ==\Last Name\==; ==|Address|==; == Age ==
==Norwegian==; Sigurd; Nordmo; [[Viggo]],\, Hansteens allé 119\; 1524 MOSS; 38
==Swede==; Chanelle; Blomqvist; Överhogdal 95\; 282 02 HÖRJA; 61
==German==; Leah; Ackermann; "Landhausstraße 73; 15702 Königs Wusterhausen"; 25
# Comments are possible. Yes, the following person is a Hobbit!
==Hobbit==; Celendine; "Gam gee"; ; 216
%%""##
%%(csv delim="semicolon")
; ==/First Name/==; ==\Last Name\==; ==|Address|==; == Age ==
==Norwegian==; Sigurd; Nordmo; [[Viggo]],\, Hansteens allé 119\; 1524 MOSS; 38
==Swede==; Chanelle; Blomqvist; Överhogdal 95\; 282 02 HÖRJA; 61
==German==; Leah; Ackermann; "Landhausstraße 73; 15702 Königs Wusterhausen"; 25
# Comments are possible. Yes, the following person is a Hobbit!
==Hobbit==; Celendine; "Gam gee"; ; 216
%%
===Changelog===
0.1 Backported from WikkaWiki
0.2 Simplified & updated to work with PHP 8 (Null coalescing assignment operator, Match expression)
0.3 Added template
===To Do===
* fix link parsing
* add additional ##$options['parameter']## and CSS class styles
* modify the formatter for your purpose
{{backlinks}}