blib/lib/Pistachio/Html.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 62 | 62 | 100.0 |
branch | 7 | 12 | 58.3 |
condition | 2 | 4 | 50.0 |
subroutine | 14 | 14 | 100.0 |
pod | 0 | 4 | 0.0 |
total | 85 | 96 | 88.5 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package Pistachio::Html; | ||||||
2 | # ABSTRACT: provides snippet(), which turns source code text into stylish HTML | ||||||
3 | |||||||
4 | 3 | 3 | 22814 | use strict; | |||
3 | 6 | ||||||
3 | 100 | ||||||
5 | 3 | 3 | 15 | use warnings; | |||
3 | 6 | ||||||
3 | 117 | ||||||
6 | our $VERSION = '0.10'; # VERSION | ||||||
7 | |||||||
8 | 3 | 3 | 578 | use Pistachio::Tokenizer; | |||
3 | 6 | ||||||
3 | 62 | ||||||
9 | 3 | 3 | 884 | use Pistachio::Language; | |||
3 | 5 | ||||||
3 | 175 | ||||||
10 | 3 | 3 | 2874 | use HTML::Entities; | |||
3 | 29205 | ||||||
3 | 356 | ||||||
11 | 3 | 3 | 34 | use Module::Load; | |||
3 | 4 | ||||||
3 | 24 | ||||||
12 | 3 | 3 | 168 | use Carp 'croak'; | |||
3 | 6 | ||||||
3 | 2602 | ||||||
13 | |||||||
14 | # @param string $type Object type. | ||||||
15 | # @param mixed $lang String: language, e.g., 'Perl5'. | ||||||
16 | # Object: A Pistachio::Language. | ||||||
17 | # @param string $style Style, e.g., 'Github'. | ||||||
18 | # @return Pistachio::Html | ||||||
19 | sub new { | ||||||
20 | 4 | 4 | 0 | 41 | my $type = shift; | ||
21 | 4 | 50 | 29 | my ($lang, $style) = (shift || '', shift || ''); | |||
50 | |||||||
22 | |||||||
23 | # A Pistachio::Css's methods return the Language-independent | ||||||
24 | # CSS definitions that correspond to the given style. | ||||||
25 | 4 | 15 | my $Css = "Pistachio::Css::${style}"; | ||||
26 | 4 | 9 | eval { load $Css }; | ||||
4 | 100 | ||||||
27 | 4 | 50 | 114 | croak "No CSS support for `$style`" if $@; | |||
28 | 4 | 26 | my $css = $Css->new; | ||||
29 | |||||||
30 | # If $lang is a Pistachio::Language, then there is no | ||||||
31 | # more work to do. If $lang is a string, attempt to | ||||||
32 | # construct a corresponding Pistachio::Language. | ||||||
33 | # (Right now, baked-in language support is limited | ||||||
34 | # to Perl5, which is tokenized via PPI::Tokenizer.) | ||||||
35 | 4 | 50 | 17 | ref $lang eq 'Pistachio::Language' or do { | |||
36 | 4 | 6 | eval { load "${Css}::${lang}", 'type_to_style' }; | ||||
4 | 22 | ||||||
37 | 4 | 50 | 347 | croak "No type_to_style() for `$lang, $style`" if $@; | |||
38 | |||||||
39 | 4 | 9 | eval { load "Pistachio::Token::Constructor::${lang}", | ||||
4 | 20 | ||||||
40 | 'text_to_tokens' }; | ||||||
41 | 4 | 50 | 375 | croak "No text_to_tokens() for `$lang`" if $@; | |||
42 | |||||||
43 | 4 | 8 | eval { load "Pistachio::Token::Transformer::${lang}", | ||||
4 | 29 | ||||||
44 | 'transform_rules' }; | ||||||
45 | 4 | 50 | 316 | croak "No transform_rules() for `$lang`" if $@; | |||
46 | |||||||
47 | $lang = Pistachio::Language->new( | ||||||
48 | $lang, | ||||||
49 | 4 | 4 | 21 | tokens => sub { text_to_tokens($_[0]) }, | |||
50 | 4 | 4 | 16 | type_to_style => sub { type_to_style($_[0]) }, | |||
51 | 23 | 23 | 62 | transform_rules => sub { transform_rules() }, | |||
52 | 4 | 69 | ); | ||||
53 | }; | ||||||
54 | |||||||
55 | 4 | 31 | bless [$lang, $css], $type; | ||||
56 | } | ||||||
57 | |||||||
58 | # @param Pistachio::Html $this | ||||||
59 | # @return A Pistachio::Language | ||||||
60 | 6 | 6 | 0 | 48 | sub lang { shift->[0] } | ||
61 | |||||||
62 | # @param Pistachio::Html $this | ||||||
63 | # @return Pistachio::Css Provides methods to access language-independent | ||||||
64 | # css definitions, for the given style. | ||||||
65 | 3 | 3 | 0 | 28 | sub css { shift->[1] } | ||
66 | |||||||
67 | # @param Pistachio::Html $this | ||||||
68 | # @param scalarref $text source code text | ||||||
69 | # @return string line numbers div + source code div html | ||||||
70 | sub snippet { | ||||||
71 | 1 | 1 | 0 | 2 | my ($this, $text) = @_; | ||
72 | |||||||
73 | 1 | 3 | NUMBER_STRIP: my $num_strip = do { | ||||
74 | 1 | 3 | my @nums = 1 .. @{[split /\n/, $$text]}; | ||||
1 | 8 | ||||||
75 | 1 | 4 | my $spec = ' %d '; |
||||
76 | 1 | 7 | my @divs = map sprintf($spec, $this->css->number_cell, $_), @nums; | ||||
77 | |||||||
78 | 1 | 3 | $spec = qq{ \n%s\n \n}; |
||||
79 | 1 | 3 | sprintf $spec, $this->css->number_strip, "@divs"; | ||||
80 | }; | ||||||
81 | |||||||
82 | 1 | 3 | CODE_DIV: my $code_div = do { | ||||
83 | 1 | 2 | my $code = ''; | ||||
84 | 1 | 5 | my $it = Pistachio::Tokenizer->new($this->lang)->iterator($text); | ||||
85 | |||||||
86 | 1 | 5 | while ($_ = $it->()) { | ||||
87 | 4 | 13 | my $style = $this->lang->type_to_style($_->type); | ||||
88 | 4 | 14 | my $val = encode_entities $_->value; | ||||
89 | 4 | 100 | 91 | $code .= $style ? qq|$val| | |||
90 | : qq|$val|; | ||||||
91 | } | ||||||
92 | |||||||
93 | 1 | 6 | sprintf qq{ %s }, $this->css->code_div, $code; |
||||
94 | }; | ||||||
95 | |||||||
96 | 1 | 10 | join "\n", ' ', $num_strip, $code_div, ' ', |
||||
97 | ''; | ||||||
98 | } | ||||||
99 | |||||||
100 | 1; | ||||||
101 | |||||||
102 | __END__ |