Compatible with: R6.1 Current version: 0.2 (beta) Credits: http://docs.wikkawiki.org/FormatterCSV |
This formatter converts inline CSV data into a table.
1. Features
- supports both
comma
(default) andsemicolon
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
2. Usage
Call via(csv [delim=[comma|semicolon])
%%(csv delim="semicolon") source%%
formatter/highlight/csv.php[link1]
<?php
/*
converts inline csv data into a table
(csv
[delim="comma|semicolon"]
)
content
*/
$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 . '/';
echo '<table class="usertable"><tbody>' . "\n";
foreach ($csv_lines as $i => $line)
{
if (preg_match('/^#|^\s*$/', $line))
{
$blanks++;
continue;
}
echo "\t" . '<tr>' . "\n";
foreach (preg_split($regex_split, $line) as $r => $field)
{
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];
}
echo "\t\t" . '<th class="' . $class[$r] . '">' . Ut::html($title[$r]) . '</th>' . "\n";
continue;
}
// if a cell is blank, echo
if (preg_match('/^\s*$/', $field))
{
echo "\t\t" . '<td class="' . $class[$r] . '"> </td>' . "\n";
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 $n => $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 $n => $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);
}
echo "\t\t" . '<td class="' . $class[$r] . '">' . $linked . '</td>' . "\n";
continue;
}
echo "\t\t" . '<td class="' . $class[$r] . '">ERROR!</td>'; // Ut::html($csv_cell)
}
echo "\t" . '</tr>' . "\n";
}
echo '</tbody></table>' . "\n";
3. 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
%%
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 |
Hobbit | Celendine | Gam gee | 216 |
4. Changelog
0.1 Backported from WikkaWiki0.2 Simplified & updated to work with PHP 8 (Null coalescing assignment operator, Match expression)
5. To Do
- fix link parsing
- add additional
$options['parameter']
and CSS class styles - modify the formatter for your purpose
Referring pages:
- Dev/PatchesHacks[link2]
- Dev/Release/R6.1/ReleaseNotes[link3]
- Dev/ReleaseNotes[link4]
- [link1] https://bitbucket.org/wackowiki/wackowiki/src/master/community/formatter/highlight/csv.php
- [link2] https://wackowiki.org/doc/Dev/PatchesHacks#a-4153
- [link3] https://wackowiki.org/doc/Dev/Release/R6.1/ReleaseNotes#a-4153
- [link4] https://wackowiki.org/doc/Dev/ReleaseNotes#a-4153