1 package IkiWiki::Plugin::table;
2 # by Victor Moral <victor@taquiones.net>
8 use IkiWiki::Plugin::mdwn;
23 hook(type => "preprocess", id => "table", call => \&preprocess);
26 sub preprocess (@) { #{{{
27 my %params = (%defaults, @_);
29 if (defined $params{delimiter}) {
30 $params{sep_char}->{$params{format}} = $params{delimiter};
32 if (defined $params{file}) {
33 if (! $pagesources{$params{file}}) {
34 return "[[table cannot find file]]";
36 $params{data} = readfile(srcfile($params{file}));
39 if (lc $params{format} eq 'auto') {
40 # first try the more simple format
41 if (is_dsv_data($params{data})) {
42 $params{format} = 'dsv';
43 $params{sep_char}->{dsv} = '\|';
46 $params{format} = 'csv';
47 $params{sep_char}->{csv} = ',';
52 if (lc $params{format} eq 'csv') {
53 @data=read_csv(\%params);
55 elsif (lc $params{format} eq 'dsv') {
56 @data=read_dsv(\%params);
59 return "[[table unknown data format]]";
63 if ($params{header} != 1) {
67 return "[[table has empty data]]";
70 my $html = tidy_up(open_table(\%params, $header),
71 build_rows(\%params, @data),
72 close_table(\%params, $header));
74 if (defined $params{file}) {
76 htmllink($params{page}, $params{destpage}, $params{file},
77 linktext => gettext('Direct data download'));
84 sub tidy_up (@) { #{{{
87 foreach my $text (@_) {
88 my $indentation = $text =~ m{thead>|tbody>} ? 0 :
90 $text =~ m{td>|th>} ? 8 :
92 $html .= (' ' x $indentation)."$text\n";
98 sub is_dsv_data ($) { #{{{
101 my ($line) = split(/\n/, $text);
102 return $line =~ m{.+\|};
105 sub read_csv ($) { #{{{
107 my @text_lines = split(/\n/, $params->{data});
109 eval q{use Text::CSV};
111 my $csv = Text::CSV->new({
112 sep_char => $params->{sep_char}->{csv},
114 }) || error("could not create a Text::CSV object");
118 foreach my $line (@text_lines) {
120 if ($csv->parse($line)) {
121 push(@data, [ $csv->fields() ]);
124 debug(sprintf(gettext('parse fail at line %d: %s'),
125 $l, $csv->error_input()));
132 sub read_dsv ($) { #{{{
134 my @text_lines = split(/\n/, $params->{data});
137 my $splitter = qr{$params->{sep_char}->{dsv}};
138 foreach my $line (@text_lines) {
139 push @data, [ split($splitter, $line) ];
145 sub open_table ($$) { #{{{
150 push @items, defined $params->{class}
151 ? "<table class=\"".$params->{class}.'">'
153 push @items, '<thead>','<tr>',
154 (map { "<th>".htmlize($params, $_)."</th>" } @$header),
155 '</tr>','</thead>' if defined $header;
156 push @items, '<tbody>';
161 sub build_rows ($@) { #{{{
165 foreach my $record (@_) {
167 (map { "<td>".htmlize($params, $_)."</td>" } @$record),
173 sub close_table ($$) { #{{{
178 push @items, '</tbody>' if defined $header;
179 push @items, '</table>';
187 $text=IkiWiki::preprocess($params->{page},
188 $params->{destpage}, $text);
189 $text=IkiWiki::htmlize($params->{page},
190 pagetype($pagesources{$params->{page}}), $text);
192 # hack to get rid of enclosing junk added by markdown