| 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 | 17 | 17 | 125 | use Moo; | ||||
| 17 | 40 | |||||||
| 17 | 125 | |||||||
| 3 | 17 | 17 | 17362 | use Storable qw( dclone ); | ||||
| 17 | 59451 | |||||||
| 17 | 27414 | |||||||
| 4 | ||||||||
| 5 | has tree => ( | |||||||
| 6 | is => 'ro', | |||||||
| 7 | ); | |||||||
| 8 | ||||||||
| 9 | has result => ( | |||||||
| 10 | is => 'ro', | |||||||
| 11 | lazy => 1, | |||||||
| 12 | 64 | 64 | 25717 | 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 | 575 | my ( $self ) = @_; | ||||
| 63 | ||||||||
| 64 | 64 | 4344 | return $self->_compile( dclone $self->tree ); | |||||
| 65 | } | |||||||
| 66 | ||||||||
| 67 | sub _compile { | |||||||
| 68 | 173 | 173 | 454 | my ( $self, $tree ) = @_; | ||||
| 69 | ||||||||
| 70 | 173 | 316 | my $str; | |||||
| 71 | ||||||||
| 72 | 173 | 258 | while ( defined ( my $node = shift @{ $tree } ) ) { | |||||
| 594 | 1448 | |||||||
| 73 | # Children should be compiled first. | |||||||
| 74 | 421 | 100 | 66 | 1011 | if ( $node->{children} and @{$node->{children}} >= 1 ) { | |||
| 109 | 384 | |||||||
| 75 | ||||||||
| 76 | # If this node can be compiled, then we will compile it, giving it the content | |||||||
| 77 | 109 | 50 | 2386 | if ( my $code = $self->can($self->functions->{$node->{class}}) ) { | ||||
| 78 | 109 | 563 | $str .= $code->($self, $node, $self->_compile(@{$node->{children}})); | |||||
| 109 | 329 | |||||||
| 79 | 109 | 306 | 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 | 5024 | if ( my $code = $self->can($self->functions->{$node->{class}}) ) { | ||||
| 87 | 312 | 2723 | $str .= $code->($self, $node); | |||||
| 88 | 312 | 800 | next; | |||||
| 89 | } else { | |||||||
| 90 | 0 | 0 | die "Error no handler found for token type " . ref($node) . "\n"; | |||||
| 91 | } | |||||||
| 92 | ||||||||
| 93 | } | |||||||
| 94 | } | |||||||
| 95 | 173 | 1086 | 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 | 4 | 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 | 142 | my ( $self, $node, $content ) = @_; | |||
| 115 | ||||||||
| 116 | 57 | 211 | return " $content \n\n"; |
|||||
| 117 | ||||||||
| 118 | } | |||||||
| 119 | ||||||||
| 120 | sub paragraph_inlinecode { | |||||||
| 121 | 2 | 2 | 0 | 6 | my ( $self, $node, $content ) = @_; | |||
| 122 | ||||||||
| 123 | 2 | 7 | 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 | 15 | my ( $self, $node, $content ) = @_; | |||
| 136 | ||||||||
| 137 | 6 | 21 | return "$content"; | |||||
| 138 | ||||||||
| 139 | } | |||||||
| 140 | ||||||||
| 141 | sub paragraph_italic { | |||||||
| 142 | 7 | 7 | 0 | 18 | my ( $self, $node, $content ) = @_; | |||
| 143 | ||||||||
| 144 | 7 | 20 | return "$content"; | |||||
| 145 | } | |||||||
| 146 | ||||||||
| 147 | sub paragraph_string { | |||||||
| 148 | 275 | 275 | 0 | 487 | my ( $self, $node ) = @_; | |||
| 149 | ||||||||
| 150 | 275 | 645 | return $node->{content}; | |||||
| 151 | ||||||||
| 152 | } | |||||||
| 153 | ||||||||
| 154 | sub paragraph_link { | |||||||
| 155 | 10 | 10 | 0 | 18 | my ( $self, $node ) = @_; | |||
| 156 | ||||||||
| 157 | 10 | 100 | 25 | 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 | 56 | ); | ||||
| 168 | } | |||||||
| 169 | ||||||||
| 170 | } | |||||||
| 171 | ||||||||
| 172 | sub paragraph_image { | |||||||
| 173 | 4 | 4 | 0 | 9 | my ( $self, $node ) = @_; | |||
| 174 | ||||||||
| 175 | 4 | 100 | 9 | if ( $node->{title} ) { | ||||
| 176 | return sprintf( ' |
|||||||
| 177 | $node->{href}, | |||||||
| 178 | $node->{title}, | |||||||
| 179 | $node->{text} | |||||||
| 180 | 1 | 8 | ); | |||||
| 181 | } else { | |||||||
| 182 | return sprintf( ' |
|||||||
| 183 | $node->{href}, | |||||||
| 184 | $node->{text} ? $node->{text} : $node->{href}, | |||||||
| 185 | 3 | 100 | 21 | ); | ||||
| 186 | } | |||||||
| 187 | } | |||||||
| 188 | ||||||||
| 189 | sub table_header_cell { | |||||||
| 190 | 3 | 3 | 0 | 12 | my ( $self, $node, $content ) = @_; | |||
| 191 | ||||||||
| 192 | 3 | 24 | return sprintf( " | %s%s | \n", $node->{content}, $content );||||
| 193 | ||||||||
| 194 | } | |||||||
| 195 | ||||||||
| 196 | sub table_cell { | |||||||
| 197 | 3 | 3 | 0 | 12 | my ( $self, $node, $content ) = @_; | |||
| 198 | ||||||||
| 199 | 3 | 16 | return sprintf( " | %s%s | \n", $node->{content}, $content );||||
| 200 | ||||||||
| 201 | } | |||||||
| 202 | ||||||||
| 203 | sub table_row { | |||||||
| 204 | 6 | 6 | 0 | 16 | my ( $self, $node, $content ) = @_; | |||
| 205 | ||||||||
| 206 | 6 | 20 | return " | |||||
| 207 | } | |||||||
| 208 | ||||||||
| 209 | sub table { | |||||||
| 210 | 3 | 3 | 0 | 13 | my ( $self, $node, $content ) = @_; | |||
| 211 | ||||||||
| 212 | 3 | 13 | return " |
|||||
| 213 | } | |||||||
| 214 | ||||||||
| 215 | sub blockquote { | |||||||
| 216 | 1 | 1 | 0 | 4 | my ( $self, $node, $content ) = @_; | |||
| 217 | ||||||||
| 218 | 1 | 5 | return "$content\n\n"; |
|||||
| 219 | } | |||||||
| 220 | ||||||||
| 221 | sub blockquote_string { | |||||||
| 222 | 5 | 5 | 0 | 11 | my ( $self, $node ) = @_; | |||
| 223 | ||||||||
| 224 | 5 | 50 | 220 | return $node->{content} || ""; | ||||
| 225 | } | |||||||
| 226 | ||||||||
| 227 | sub codeblock { | |||||||
| 228 | 2 | 2 | 0 | 6 | my ( $self, $node, $content ) = @_; | |||
| 229 | ||||||||
| 230 | return $node->{language} | |||||||
| 231 | 2 | 50 | 10 | ? "\n\n" |
||||
| 232 | : "\n\n" |
|||||||
| 233 | } | |||||||
| 234 | ||||||||
| 235 | sub codeblock_string { | |||||||
| 236 | 6 | 6 | 0 | 62 | my ( $self, $node ) = @_; | |||
| 237 | ||||||||
| 238 | 6 | 18 | return $node->{content}; | |||||
| 239 | ||||||||
| 240 | } | |||||||
| 241 | ||||||||
| 242 | sub ordered_list { | |||||||
| 243 | 1 | 1 | 0 | 3 | my ( $self, $node, $content ) = @_; | |||
| 244 | ||||||||
| 245 | 1 | 5 | return "
|
|||||
| 246 | ||||||||
| 247 | } | |||||||
| 248 | ||||||||
| 249 | sub unordered_list { | |||||||
| 250 | 4 | 4 | 0 | 16 | my ( $self, $node, $content ) = @_; | |||
| 251 | ||||||||
| 252 | 4 | 14 | return "
|
|||||
| 253 | ||||||||
| 254 | } | |||||||
| 255 | ||||||||
| 256 | sub list_item { | |||||||
| 257 | 13 | 13 | 0 | 32 | my ( $self, $node, $content ) = @_; | |||
| 258 | ||||||||
| 259 | 13 | 37 | return " |
|||||
| 260 | ||||||||
| 261 | } | |||||||
| 262 | ||||||||
| 263 | sub list_item_string { | |||||||
| 264 | 12 | 12 | 0 | 25 | my ( $self, $node ) = @_; | |||
| 265 | ||||||||
| 266 | 12 | 31 | 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; |