fa43a43a023c82f191d0eb109a11ffdc4896b66c
[scpubgit/System-Introspector-Report.git] / lib / System / Introspector / Report / Publish / MediaWiki / Producer.pm
1 package System::Introspector::Report::Publish::MediaWiki::Producer;
2 use Moo;
3 use HTML::Zoom;
4
5 sub render {
6   my ($self, $stream) = @_;
7   return join "\n", map {
8     ref($_) ? $self->_render_table($_) : $_;
9   } @$stream;
10 }
11
12 sub _wrap {
13   my ($self, $type, $id, $body) = @_;
14   chomp $body;
15   return join "\n",
16     sprintf('<!-- SI:%s begin %s -->', uc($type), $id),
17     $body,
18     sprintf('<!-- SI:%s end %s -->', uc($type), $id),
19 }
20
21 sub _render_table {
22   my ($self, $report) = @_;
23   my $id     = $report->{id};
24   my $str_id = ref($id) ? join(':', @$id) : $id;
25   my $markup = $self->_load_markup;
26   $markup = $self->_apply_identity($markup, $report);
27   $markup = $self->_apply_table_head($markup, $report);
28   $markup = $self->_apply_table_body($markup, $report);
29   my $description = $report->{description} || [''];
30   return join "\n",
31     $self->_wrap('title', $str_id, $self->_render_title($report)),
32     @$description,
33     $self->_wrap('table', $str_id, $markup->to_html),
34     '';
35 }
36
37 sub _render_title {
38   my ($self, $report) = @_;
39   return sprintf '== %s ==', $report->{title};
40 }
41
42 sub _apply_identity {
43   my ($self, $markup, $report) = @_;
44   my $id = $report->{id};
45   return $markup
46     ->select('table')
47     ->set_attribute(id => 'si-id-' . join '__',
48       ref($id) ? @$id : $id,
49     );
50 }
51
52 sub _apply_table_body {
53   my ($self, $markup, $report) = @_;
54   my $index = 0;
55   my $rows  = $report->{rows};
56   my @cols  = map $_->{key}, @{$report->{columns}};
57   return $markup->repeat('.data-row', sub {
58     return HTML::Zoom::CodeStream->new({
59       code => sub {
60         return if $index > $#$rows;
61         my $row = $rows->[$index++];
62         return sub {
63           $_->repeat('td', [ map {
64             my $col_idx = $_;
65             my $col = $cols[$_];
66             my $value = $row->{$col};
67             sub {
68               $_->apply_if($col !~ m{^__}, sub {
69                   $_->add_to_attribute('td', class => "si-column-$col");
70                 })
71                 ->replace_content('td', defined($value) ? $value : '')
72                 ->apply_if($col_idx != $#cols, sub {
73                   $_->add_after('td', "\n    ");
74                 });
75             };
76           } 0 .. $#cols ]);
77         };
78       },
79     });
80   });
81 }
82
83 sub _apply_table_head {
84   my ($self, $markup, $report) = @_;
85   my @cols = @{$report->{columns}};
86   return $markup
87     ->repeat('th', [map {
88       my $col_idx = $_;
89       my $col = $cols[$_];
90       sub {
91         $_->apply_if($col->{key} !~ m{^__}, sub {
92             $_->add_to_attribute('th', class => 'si-colhead-' . $col->{key});
93           })
94           ->replace_content('th', $col->{label})
95           ->apply_if($col_idx != $#cols, sub {
96             $_->add_after('th', "\n    ");
97           });
98       };
99     } 0 .. $#cols ])
100 }
101
102 sub _load_markup {
103   return HTML::Zoom->from_html(do {
104     local $/;
105     scalar <DATA>;
106   });
107 }
108
109 1;
110
111 __DATA__
112 <table class="si-report">
113   <tr>
114     <th>Header</th>
115   </tr>
116   <tr class="data-row">
117     <td>Value</td>
118   </tr>
119 </table>