Skip to content

Instantly share code, notes, and snippets.

@timo
Last active July 20, 2016 22:52
Show Gist options
  • Save timo/6132249 to your computer and use it in GitHub Desktop.
Save timo/6132249 to your computer and use it in GitHub Desktop.
new table grammar
grammar Table {
token TOP {
<pod_block>
}
token pod_newline {
\h* \n
}
method insert_column_part($text, $column, @text-pieces, @columns, $columns-fixed = False) {
say "$text, $column";
for @columns.kv -> $idx, $pos {
if $pos == $column {
say @text-pieces.perl; say $idx.perl;
push @text-pieces[$idx], $text;
return;
} elsif $pos > $column && !$columns-fixed {
@text-pieces.splice($idx, 0, Array.new.push($text).item);
@columns.splice($idx, 0, $column);
return;
} elsif $pos > $column && $columns-fixed {
# maybe the user wanted to use multiple spaces to align.
# that's no problem if our colums are already fixed,
# because we already know the exact layout of columns.
my $lr := @text-pieces[$idx - 1];
$lr.push: $lr.pop() ~ " " ~ $text;
return;
}
}
if !$columns-fixed {
@text-pieces.push(Array.new.push($text).item);
@columns.push($column);
} else {
say "dropped text: $text";
}
}
token table_row(@content, @headers, @text-pieces, @columns) {
:my $pos-of-newline;
{ $pos-of-newline = $/.CURSOR.pos; }
[\h* ['|'\h+]?]
<!before '=end table'>
[$<column>=[\S [\S|\h<!before \h|'|'>]*]]+ % [\h (\h+ | \h* '|' \h+)?]
{
for $<column>.kv -> $idx, $_ {
next if ~$_ eq '|';
self.insert_column_part(~$_, $_.from - $pos-of-newline, @text-pieces, @columns, !$*before-header);
}
}
[
|| <.pod_newline> ['='|'-'|'|'|\h]* <.pod_newline>
{
if +@headers == 0 {
@headers = @text-pieces.map: *.join(" ");
$*before-header = False;
} else {
push @content, @text-pieces.map(*.join(" ")).item;
}
@text-pieces = Nil;
}
|| <.pod_newline>
]
}
token pod_block {
:my @columns;
:my @text-pieces;
:my @headers;
:my $pos-of-newline;
:my $col-idx = -1;
:my $hsep;
:my $*before-header = True;
:my @content;
$<spaces>=[\h*]
"=begin table" $<config>=[' ' \N*]? <.pod_newline>
[ $<spaces> <table_row(@content, @headers, @text-pieces, @columns)> ]+
$<spaces> "=end table"
{
if +@text-pieces {
for ^(+@text-pieces[0]) {
push @content, (@text-pieces.map: *.shift).item;
}
}
say @headers.perl;
say @content.perl;
}
}
}
my @tabledata = q:to/END/, q:to/END/, q:to/END/;
=begin table :caption('The Other Guys')
Superhero Secret
Identity Superpower
============= =============== ===================
The Shoveller Eddie Stevens King Arthur's
singing shovel
Blue Raja Geoffrey Smith Master of cutlery
Mr Furious Roy Orson Ticking time bomb
of fury
The Bowler Carol Pinnsler Haunted bowling ball
=end table
END
=begin table
Superhero | Secret |
| Identity | Superpower
================|=================|================================
The Shoveller | Eddie Stevens | King Arthur's singing shovel
Blue Raja | Geoffrey Smith | Master of cutlery
Mr Furious | Roy Orson | Ticking time bomb of fury
The Bowler | Carol Pinnsler | Haunted bowling ball
=end table
END
=begin table
The Shoveller Eddie Stevens King Arthur's singing shovel
Blue Raja Geoffrey Smith Master of cutlery
Mr Furious Roy Orson Ticking time bomb of fury
The Bowler Carol Pinnsler Haunted bowling ball
=end table
END
say Table.parse($_) for @tabledata;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment