blib/lib/Markdown/Compiler/Target/HTML.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 68 | 74 | 91.8 |
branch | 13 | 16 | 81.2 |
condition | 3 | 5 | 60.0 |
subroutine | 25 | 28 | 89.2 |
pod | 0 | 23 | 0.0 |
total | 109 | 146 | 74.6 |
line | stmt | bran | cond | sub | pod | time | code | |
---|---|---|---|---|---|---|---|---|
1 | package Markdown::Compiler::Target::HTML; | |||||||
2 | 18 | 18 | 114 | use Moo; | ||||
18 | 38 | |||||||
18 | 101 | |||||||
3 | 18 | 18 | 15747 | use Storable qw( dclone ); | ||||
18 | 52850 | |||||||
18 | 23432 | |||||||
4 | ||||||||
5 | has tree => ( | |||||||
6 | is => 'ro', | |||||||
7 | ); | |||||||
8 | ||||||||
9 | has result => ( | |||||||
10 | is => 'ro', | |||||||
11 | lazy => 1, | |||||||
12 | 64 | 64 | 21939 | builder => sub { shift->html }, | ||||
13 | ); | |||||||
14 | ||||||||
15 | has html => ( | |||||||
16 | is => 'ro', | |||||||
17 | lazy => 1, | |||||||
18 | builder => '_build_html', | |||||||
19 | ); | |||||||
20 | ||||||||
21 | has functions => ( | |||||||
22 | is => 'ro', | |||||||
23 | lazy => 1, | |||||||
24 | default => sub { | |||||||
25 | return +{ | |||||||
26 | 'Markdown::Compiler::Parser::Node::Metadata' => 'noop', | |||||||
27 | ||||||||
28 | 'Markdown::Compiler::Parser::Node::Header' => 'header', | |||||||
29 | ||||||||
30 | 'Markdown::Compiler::Parser::Node::HR' => 'hr', | |||||||
31 | ||||||||
32 | 'Markdown::Compiler::Parser::Node::Paragraph' => 'paragraph', | |||||||
33 | 'Markdown::Compiler::Parser::Node::Paragraph::InlineCode' => 'paragraph_inlinecode', | |||||||
34 | 'Markdown::Compiler::Parser::Node::Paragraph::BoldItalic' => 'paragraph_bolditalic', | |||||||
35 | 'Markdown::Compiler::Parser::Node::Paragraph::Bold' => 'paragraph_bold', | |||||||
36 | 'Markdown::Compiler::Parser::Node::Paragraph::Italic' => 'paragraph_italic', | |||||||
37 | 'Markdown::Compiler::Parser::Node::Paragraph::String' => 'paragraph_string', | |||||||
38 | 'Markdown::Compiler::Parser::Node::Paragraph::Link' => 'paragraph_link', | |||||||
39 | 'Markdown::Compiler::Parser::Node::Paragraph::Image' => 'paragraph_image', | |||||||
40 | ||||||||
41 | 'Markdown::Compiler::Parser::Node::Table' => 'table', | |||||||
42 | 'Markdown::Compiler::Parser::Node::Table::Row' => 'table_row', | |||||||
43 | 'Markdown::Compiler::Parser::Node::Table::Cell' => 'table_cell', | |||||||
44 | 'Markdown::Compiler::Parser::Node::Table::HeaderCell' => 'table_header_cell', | |||||||
45 | ||||||||
46 | 'Markdown::Compiler::Parser::Node::BlockQuote' => 'blockquote', | |||||||
47 | 'Markdown::Compiler::Parser::Node::BlockQuote::String' => 'blockquote_string', | |||||||
48 | ||||||||
49 | 'Markdown::Compiler::Parser::Node::CodeBlock' => 'codeblock', | |||||||
50 | 'Markdown::Compiler::Parser::Node::CodeBlock::String' => 'codeblock_string', | |||||||
51 | ||||||||
52 | 'Markdown::Compiler::Parser::Node::List::Ordered' => 'ordered_list', | |||||||
53 | 'Markdown::Compiler::Parser::Node::List::Unordered' => 'unordered_list', | |||||||
54 | 'Markdown::Compiler::Parser::Node::List::Unordered::Item' => 'list_item', | |||||||
55 | 'Markdown::Compiler::Parser::Node::List::Ordered::Item' => 'list_item', | |||||||
56 | 'Markdown::Compiler::Parser::Node::List::Item::String' => 'list_item_string', | |||||||
57 | } | |||||||
58 | } | |||||||
59 | ); | |||||||
60 | ||||||||
61 | sub _build_html { | |||||||
62 | 64 | 64 | 564 | my ( $self ) = @_; | ||||
63 | ||||||||
64 | 64 | 4051 | return $self->_compile( dclone $self->tree ); | |||||
65 | } | |||||||
66 | ||||||||
67 | sub _compile { | |||||||
68 | 173 | 173 | 376 | my ( $self, $tree ) = @_; | ||||
69 | ||||||||
70 | 173 | 232 | my $str; | |||||
71 | ||||||||
72 | 173 | 270 | while ( defined ( my $node = shift @{ $tree } ) ) { | |||||
594 | 1183 | |||||||
73 | # Children should be compiled first. | |||||||
74 | 421 | 100 | 66 | 857 | if ( $node->{children} and @{$node->{children}} >= 1 ) { | |||
109 | 351 | |||||||
75 | ||||||||
76 | # If this node can be compiled, then we will compile it, giving it the content | |||||||
77 | 109 | 50 | 1851 | if ( my $code = $self->can($self->functions->{$node->{class}}) ) { | ||||
78 | 109 | 495 | $str .= $code->($self, $node, $self->_compile(@{$node->{children}})); | |||||
109 | 329 | |||||||
79 | 109 | 333 | next; | |||||
80 | } | |||||||
81 | 0 | 0 | warn "This is an odd place to be.... children but the parent can't be compiled?"; | |||||
82 | } | |||||||
83 | ||||||||
84 | # This node has no children to compile. | |||||||
85 | else { | |||||||
86 | 312 | 50 | 4122 | if ( my $code = $self->can($self->functions->{$node->{class}}) ) { | ||||
87 | 312 | 2222 | $str .= $code->($self, $node); | |||||
88 | 312 | 703 | next; | |||||
89 | } else { | |||||||
90 | 0 | 0 | die "Error no handler found for token type " . ref($node) . "\n"; | |||||
91 | } | |||||||
92 | ||||||||
93 | } | |||||||
94 | } | |||||||
95 | 173 | 1093 | return $str; | |||||
96 | } | |||||||
97 | ||||||||
98 | 0 | 0 | 0 | 0 | sub noop { "" } | |||
99 | ||||||||
100 | sub header { | |||||||
101 | 1 | 1 | 0 | 4 | my ( $self, $node, $content ) = @_; | |||
102 | ||||||||
103 | 1 | 3 | my $header = "h" . $node->{size}; | |||||
104 | ||||||||
105 | 1 | 6 | return "<$header>$content$header>\n\n"; | |||||
106 | ||||||||
107 | } | |||||||
108 | ||||||||
109 | sub hr { | |||||||
110 | 0 | 0 | 0 | 0 | return " "; |
|||
111 | } | |||||||
112 | ||||||||
113 | sub paragraph { | |||||||
114 | 57 | 57 | 0 | 189 | my ( $self, $node, $content ) = @_; | |||
115 | ||||||||
116 | 57 | 186 | return " $content \n\n"; |
|||||
117 | ||||||||
118 | } | |||||||
119 | ||||||||
120 | sub paragraph_inlinecode { | |||||||
121 | 2 | 2 | 0 | 7 | my ( $self, $node, $content ) = @_; | |||
122 | ||||||||
123 | 2 | 5 | return '' . $content . ''; | |||||
124 | ||||||||
125 | } | |||||||
126 | ||||||||
127 | sub paragraph_bolditalic { | |||||||
128 | 0 | 0 | 0 | 0 | my ( $self, $node, $content ) = @_; | |||
129 | ||||||||
130 | 0 | 0 | return "$content"; | |||||
131 | ||||||||
132 | } | |||||||
133 | ||||||||
134 | sub paragraph_bold { | |||||||
135 | 6 | 6 | 0 | 12 | my ( $self, $node, $content ) = @_; | |||
136 | ||||||||
137 | 6 | 15 | return "$content"; | |||||
138 | ||||||||
139 | } | |||||||
140 | ||||||||
141 | sub paragraph_italic { | |||||||
142 | 7 | 7 | 0 | 19 | my ( $self, $node, $content ) = @_; | |||
143 | ||||||||
144 | 7 | 28 | return "$content"; | |||||
145 | } | |||||||
146 | ||||||||
147 | sub paragraph_string { | |||||||
148 | 275 | 275 | 0 | 413 | my ( $self, $node ) = @_; | |||
149 | ||||||||
150 | 275 | 544 | return $node->{content}; | |||||
151 | ||||||||
152 | } | |||||||
153 | ||||||||
154 | sub paragraph_link { | |||||||
155 | 10 | 10 | 0 | 17 | my ( $self, $node ) = @_; | |||
156 | ||||||||
157 | 10 | 100 | 15 | if ( $node->{title} ) { | ||||
158 | return sprintf( '%s', | |||||||
159 | $node->{href}, | |||||||
160 | $node->{title}, | |||||||
161 | $node->{text}, | |||||||
162 | 1 | 8 | ); | |||||
163 | } else { | |||||||
164 | return sprintf( '%s', | |||||||
165 | $node->{href}, | |||||||
166 | $node->{text} ? $node->{text} : $node->{href}, | |||||||
167 | 9 | 100 | 49 | ); | ||||
168 | } | |||||||
169 | ||||||||
170 | } | |||||||
171 | ||||||||
172 | sub paragraph_image { | |||||||
173 | 4 | 4 | 0 | 8 | my ( $self, $node ) = @_; | |||
174 | ||||||||
175 | 4 | 100 | 12 | if ( $node->{title} ) { | ||||
176 | return sprintf( '', | |||||||
177 | $node->{href}, | |||||||
178 | $node->{title}, | |||||||
179 | $node->{text} | |||||||
180 | 1 | 9 | ); | |||||
181 | } else { | |||||||
182 | return sprintf( '', | |||||||
183 | $node->{href}, | |||||||
184 | $node->{text} ? $node->{text} : $node->{href}, | |||||||
185 | 3 | 100 | 26 | ); | ||||
186 | } | |||||||
187 | } | |||||||
188 | ||||||||
189 | sub table_header_cell { | |||||||
190 | 3 | 3 | 0 | 9 | my ( $self, $node, $content ) = @_; | |||
191 | ||||||||
192 | 3 | 15 | return sprintf( " | %s%s | \n", $node->{content}, $content );||||
193 | ||||||||
194 | } | |||||||
195 | ||||||||
196 | sub table_cell { | |||||||
197 | 3 | 3 | 0 | 10 | my ( $self, $node, $content ) = @_; | |||
198 | ||||||||
199 | 3 | 10 | return sprintf( " | %s%s | \n", $node->{content}, $content );||||
200 | ||||||||
201 | } | |||||||
202 | ||||||||
203 | sub table_row { | |||||||
204 | 6 | 6 | 0 | 13 | my ( $self, $node, $content ) = @_; | |||
205 | ||||||||
206 | 6 | 14 | return " | |||||
207 | } | |||||||
208 | ||||||||
209 | sub table { | |||||||
210 | 3 | 3 | 0 | 8 | my ( $self, $node, $content ) = @_; | |||
211 | ||||||||
212 | 3 | 9 | return " |
|||||
213 | } | |||||||
214 | ||||||||
215 | sub blockquote { | |||||||
216 | 1 | 1 | 0 | 2 | my ( $self, $node, $content ) = @_; | |||
217 | ||||||||
218 | 1 | 4 | return "$content\n\n"; |
|||||
219 | } | |||||||
220 | ||||||||
221 | sub blockquote_string { | |||||||
222 | 5 | 5 | 0 | 9 | my ( $self, $node ) = @_; | |||
223 | ||||||||
224 | 5 | 50 | 15 | return $node->{content} || ""; | ||||
225 | } | |||||||
226 | ||||||||
227 | sub codeblock { | |||||||
228 | 2 | 2 | 0 | 5 | my ( $self, $node, $content ) = @_; | |||
229 | ||||||||
230 | return $node->{language} | |||||||
231 | 2 | 50 | 8 | ? " \n\n" |
||||
232 | : " \n\n" |
|||||||
233 | } | |||||||
234 | ||||||||
235 | sub codeblock_string { | |||||||
236 | 6 | 6 | 0 | 10 | my ( $self, $node ) = @_; | |||
237 | ||||||||
238 | 6 | 12 | return $node->{content}; | |||||
239 | ||||||||
240 | } | |||||||
241 | ||||||||
242 | sub ordered_list { | |||||||
243 | 1 | 1 | 0 | 3 | my ( $self, $node, $content ) = @_; | |||
244 | ||||||||
245 | 1 | 2 | return "
|
|||||
246 | ||||||||
247 | } | |||||||
248 | ||||||||
249 | sub unordered_list { | |||||||
250 | 4 | 4 | 0 | 10 | my ( $self, $node, $content ) = @_; | |||
251 | ||||||||
252 | 4 | 12 | return "
|
|||||
253 | ||||||||
254 | } | |||||||
255 | ||||||||
256 | sub list_item { | |||||||
257 | 13 | 13 | 0 | 26 | my ( $self, $node, $content ) = @_; | |||
258 | ||||||||
259 | 13 | 37 | return " |
|||||
260 | ||||||||
261 | } | |||||||
262 | ||||||||
263 | sub list_item_string { | |||||||
264 | 12 | 12 | 0 | 20 | my ( $self, $node ) = @_; | |||
265 | ||||||||
266 | 12 | 22 | return $node->{content}; | |||||
267 | } | |||||||
268 | ||||||||
269 | ||||||||
270 | ||||||||
271 | ||||||||
272 | ||||||||
273 | ||||||||
274 | ||||||||
275 | # package Markdown::Compiler::Parser::Node; | |||||||
276 | # package Markdown::Compiler::Parser::Node::Header; | |||||||
277 | # package Markdown::Compiler::Parser::Node::HR; | |||||||
278 | # package Markdown::Compiler::Parser::Node::Paragraph; | |||||||
279 | # package Markdown::Compiler::Parser::Node::Paragraph::BoldItalic; | |||||||
280 | # package Markdown::Compiler::Parser::Node::Paragraph::Bold; | |||||||
281 | # package Markdown::Compiler::Parser::Node::Paragraph::Italic; | |||||||
282 | # package Markdown::Compiler::Parser::Node::Paragraph::String; | |||||||
283 | # package Markdown::Compiler::Parser::Node::Paragraph::Link; | |||||||
284 | # package Markdown::Compiler::Parser::Node::Paragraph::Image; | |||||||
285 | # package Markdown::Compiler::Parser::Node::Table; | |||||||
286 | # package Markdown::Compiler::Parser::Node::Blockquote; | |||||||
287 | # package Markdown::Compiler::Parser::Node::Codeblock; | |||||||
288 | # package Markdown::Compiler::Parser::Node::List; | |||||||
289 | ||||||||
290 | ||||||||
291 | ||||||||
292 | 1; |