Formatter: CSV
Compatible with: R6.1 Current version: 0.3 (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
%%
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
if (preg_match('/^\s*$/', $field))
{
$tpl->t_class = $class[$r];
$tpl->t_cell = ' ';
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);
}
$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_
formatter/highlight/template/csv.tpl[link2]
[ === 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>
2.1. 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
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)
0.3 Added template
5. To Do
- fix link parsing
- add additional
$options['parameter']
and CSS class styles - modify the formatter for your purpose
Referring pages:
- Dev/PatchesHacks[link3]
- Dev/Release/R6.1/ReleaseNotes[link4]
- Dev/ReleaseNotes[link5]
- [link1] https://bitbucket.org/wackowiki/wackowiki/src/master/community/formatter/highlight/csv.php
- [link2] https://bitbucket.org/wackowiki/wackowiki/src/master/community/formatter/highlight/template/csv.tpl
- [link3] https://wackowiki.org/doc/Dev/PatchesHacks#a-4153
- [link4] https://wackowiki.org/doc/Dev/Release/R6.1/ReleaseNotes#a-4153
- [link5] https://wackowiki.org/doc/Dev/ReleaseNotes#a-4153