Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Handle a one-lined table with a header. Add a skeleton for handling a…
… multi-line tables
  • Loading branch information
Tadeusz Sośnierz committed Jul 5, 2011
1 parent fbb1956 commit 458689d
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 6 deletions.
62 changes: 57 additions & 5 deletions lib/Pod6/Actions.pm
Expand Up @@ -129,19 +129,71 @@ class Pod6::Actions {
}

method table($/) {
return Pod6::Block::Table.new(
content => $<table_content>.ast.list
);
return $<table_content>.ast;
}

method table_content($/) {
make $<table_row>».ast;
my @rows = $<table_row>».ast;
# we need 3 informations about the separators:
# how many of them are
# where is the first one
# are they different from each other
# Given no separators, our table is just an ordinary, one-lined
# table.
# If there is one separator, the table has a header and
# the actual content. If the first header is further than on the
# second row, then the header is multi-lined.
# If there's more than one separator, the table has a multi-line
# header and a multi-line content.
# Tricky, isn't it? Let's try to handle it sanely
my $sepnum = 0;
my $firstsepindex = 0;
my $differentseps = 0;
my $firstsep;
for @rows.kv -> $k, $v {
if $v ~~ Str {
$sepnum++;
$firstsepindex or $firstsepindex = $k;
if $firstsep {
if $firstsep ne $v { $differentseps = 1 }
} else {
$firstsep = $v;
}
}
}
if $sepnum == 0 {
# ordinary table, nothing fancy
make Pod6::Block::Table.new(content => @rows);
} elsif $sepnum == 1 {
# header and a table
if $firstsepindex == 1 {
# one-lined header and a one-lined table
say '# one-lined header and a one-lined table';
my @head = @rows.shift.list;
@rows.shift;
make Pod6::Block::Table.new(
headers => @head,
content => @rows,
);
} else {
# multi-line header and a one-lined-table
say '# multi-line header and a one-lined-table';
make Pod6::Block::Table.new;
}
} else {
say '# multi-lined header and multi-lined table';
make Pod6::Block::Table.new;
}
}

method table_row($/) {
method table_row:sym<content>($/) {
make $<table_cell>».ast
}

method table_row:sym<separator>($/) {
make ~$/
}

method table_cell($/) {
make $/.Str;
}
Expand Down
10 changes: 9 additions & 1 deletion lib/Pod6/Grammar.pm
Expand Up @@ -156,10 +156,18 @@ grammar Pod6::Grammar {
<table_row>+
}

token table_row {
proto token table_row {
<...>
}

token table_row:sym<content> {
\h* <table_cell> ** [ \h+'|'\h+ || \h+'+'\h+ || \h\h+ ] \n
}

token table_row:sym<separator> {
\h* [\h+ || '+'+ || '-'+ || '='+ || '_'+ ] \n
}

token table_cell {
<!before '=' \w> # no pod directives
[
Expand Down
25 changes: 25 additions & 0 deletions t/08-tables.t
Expand Up @@ -64,4 +64,29 @@ is $r.content[1][1], 'horses';
is $r.content[2][0], 'elephant';
is $r.content[2][1], 'elephants';

# disclamer: DO NOT treat this test as a source of knowlegde about fauna
$x = q[
=table
Animal | Legs | Eats
=======================
Zebra | 4 | Cookies
Human | 2 | Pizza
Shark | 0 | Fish
];

$r = Pod6::parse($x);
is $r.headers[0], 'Animal';
is $r.headers[1], 'Legs';
is $r.headers[2], 'Eats';
is $r.content[0][0], 'Zebra';
is $r.content[0][1], '4';
is $r.content[0][1], '4';
is $r.content[0][2], 'Cookies';
is $r.content[1][0], 'Human';
is $r.content[1][1], '2';
is $r.content[1][2], 'Pizza';
is $r.content[2][0], 'Shark';
is $r.content[2][1], '0';
is $r.content[2][2], 'Fish';

done;

0 comments on commit 458689d

Please sign in to comment.