blib/lib/Kwim/HTML.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 111 | 123 | 90.2 |
branch | 29 | 40 | 72.5 |
condition | n/a | ||
subroutine | 25 | 27 | 92.5 |
pod | 0 | 22 | 0.0 |
total | 165 | 212 | 77.8 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | 2 | 2 | 2902 | use strict; use warnings; | |||
2 | 2 | 6 | |||||
2 | 85 | ||||||
2 | 11 | ||||||
2 | 5 | ||||||
2 | 361 | ||||||
2 | package Kwim::HTML; | ||||||
3 | |||||||
4 | 2 | 2 | 13 | use base 'Kwim::Markup'; | |||
2 | 4 | ||||||
2 | 795 | ||||||
5 | # use XXX -with => 'YAML::XS'; | ||||||
6 | |||||||
7 | 2 | 2 | 2034 | use HTML::Escape; | |||
2 | 5971 | ||||||
2 | 268 | ||||||
8 | |||||||
9 | 2 | 2 | 17 | use constant top_block_separator => "\n"; | |||
2 | 5 | ||||||
2 | 5997 | ||||||
10 | |||||||
11 | my $document_title = ''; | ||||||
12 | my $info = { | ||||||
13 | verse => { | ||||||
14 | tag => 'p', | ||||||
15 | style => 'block', | ||||||
16 | transform => 'transform_verse', | ||||||
17 | attrs => ' class="verse"', | ||||||
18 | }, | ||||||
19 | }; | ||||||
20 | |||||||
21 | sub render_text { | ||||||
22 | 51 | 51 | 0 | 100 | my ($self, $text) = @_; | ||
23 | 51 | 111 | $text =~ s/\n/ /g; | ||||
24 | 51 | 268 | escape_html($text); | ||||
25 | } | ||||||
26 | |||||||
27 | sub render_para { | ||||||
28 | 41 | 41 | 0 | 92 | my ($self, $node) = @_; | ||
29 | 41 | 147 | my $out = $self->render($node); | ||||
30 | 41 | 116 | chomp $out; | ||||
31 | 41 | 50 | 169 | my $spacer = $out =~ /\n/ ? "\n" : ''; | |||
32 | 41 | 181 | " $spacer$out$spacer \n"; |
||||
33 | } | ||||||
34 | |||||||
35 | sub render_rule { | ||||||
36 | 1 | 1 | 0 | 5 | " \n"; |
||
37 | } | ||||||
38 | |||||||
39 | sub render_blank { | ||||||
40 | 5 | 5 | 0 | 13 | " \n"; |
||
41 | } | ||||||
42 | |||||||
43 | sub render_list { | ||||||
44 | 2 | 2 | 0 | 5 | my ($self, $node) = @_; | ||
45 | 2 | 7 | my $out = $self->render($node); | ||||
46 | 2 | 7 | chomp $out; | ||||
47 | 2 | 9 | "
|
||||
48 | } | ||||||
49 | |||||||
50 | sub render_item { | ||||||
51 | 5 | 5 | 0 | 8 | my ($self, $node) = @_; | ||
52 | 5 | 16 | my $out = $self->render($node); | ||||
53 | 5 | 33 | $out =~ s/(.)(<(?:ul|pre|p)(?: |>))/$1\n$2/; | ||||
54 | 5 | 100 | 21 | my $spacer = $out =~ /\n/ ? "\n" : ''; | |||
55 | 5 | 25 | " |
||||
56 | } | ||||||
57 | |||||||
58 | sub render_pref { | ||||||
59 | 2 | 2 | 0 | 5 | my ($self, $node) = @_; | ||
60 | 2 | 9 | my $out = escape_html($node); | ||||
61 | 2 | 12 | " \n"; |
||||
62 | } | ||||||
63 | |||||||
64 | sub render_func { | ||||||
65 | 17 | 17 | 0 | 44 | my ($self, $node) = @_; | ||
66 | 17 | 50 | 197 | if ($node =~ /^(\w[\-\w]*) ?((?s:.*)?)$/) { | |||
67 | 17 | 103 | my ($name, $args) = ($1, $2); | ||||
68 | 17 | 43 | $name =~ s/-/_/g; | ||||
69 | 17 | 47 | my $method = "phrase_func_$name"; | ||||
70 | 17 | 50 | 116 | if ($self->can($method)) { | |||
71 | 17 | 69 | my $out = $self->$method($args); | ||||
72 | 17 | 50 | 104 | return $out if defined $out; | |||
73 | } | ||||||
74 | } | ||||||
75 | 0 | 0 | "<$node>"; | ||||
76 | } | ||||||
77 | |||||||
78 | sub render_title { | ||||||
79 | 1 | 1 | 0 | 3 | my ($self, $node) = @_; | ||
80 | 1 | 5 | my $out = $self->render($node); | ||||
81 | 1 | 4 | chomp $out; | ||||
82 | 1 | 50 | 6 | my ($name, $text) = ref $node ? @$node : (undef, $node); | |||
83 | 1 | 50 | 3 | if (defined $text) { | |||
84 | 0 | 0 | $document_title = "$name - $text"; | ||||
85 | 0 | 0 | "$name\n\n$text \n"; |
||||
86 | } | ||||||
87 | else { | ||||||
88 | 1 | 3 | $document_title = "$name"; | ||||
89 | 1 | 50 | 23 | my $spacer = $name =~ /\n/ ? "\n" : ''; | |||
90 | 1 | 7 | "$spacer$name$spacer\n"; |
||||
91 | } | ||||||
92 | } | ||||||
93 | |||||||
94 | sub render_head { | ||||||
95 | 3 | 3 | 0 | 6 | my ($self, $node, $number) = @_; | ||
96 | 3 | 10 | my $out = $self->render($node); | ||||
97 | 3 | 5 | chomp $out; | ||||
98 | 3 | 16 | " |
||||
99 | } | ||||||
100 | |||||||
101 | sub render_comment { | ||||||
102 | 3 | 3 | 0 | 6 | my ($self, $node) = @_; | ||
103 | 3 | 15 | my $out = escape_html($node); | ||||
104 | 3 | 100 | 11 | if ($out =~ /\n/) { | |||
105 | 1 | 3 | "\n"; | ||||
106 | } | ||||||
107 | else { | ||||||
108 | 2 | 9 | "\n"; | ||||
109 | } | ||||||
110 | } | ||||||
111 | |||||||
112 | sub render_code { | ||||||
113 | 2 | 2 | 0 | 5 | my ($self, $node) = @_; | ||
114 | 2 | 11 | my $out = $self->render($node); | ||||
115 | 2 | 10 | "$out "; |
||||
116 | } | ||||||
117 | |||||||
118 | sub render_bold { | ||||||
119 | 3 | 3 | 0 | 10 | my ($self, $node) = @_; | ||
120 | 3 | 13 | my $out = $self->render($node); | ||||
121 | 3 | 14 | "$out"; | ||||
122 | } | ||||||
123 | |||||||
124 | sub render_emph { | ||||||
125 | 2 | 2 | 0 | 7 | my ($self, $node) = @_; | ||
126 | 2 | 12 | my $out = $self->render($node); | ||||
127 | 2 | 9 | "$out"; | ||||
128 | } | ||||||
129 | |||||||
130 | sub render_del { | ||||||
131 | 4 | 4 | 0 | 11 | my ($self, $node) = @_; | ||
132 | 4 | 16 | my $out = $self->render($node); | ||||
133 | 4 | 18 | " |
||||
134 | } | ||||||
135 | |||||||
136 | sub render_hyper { | ||||||
137 | 3 | 3 | 0 | 8 | my ($self, $node) = @_; | ||
138 | 3 | 6 | my ($link, $text) = @{$node}{qw(link text)}; | ||||
3 | 10 | ||||||
139 | 3 | 100 | 13 | $text = $link if not length $text; | |||
140 | 3 | 15 | "$text"; | ||||
141 | } | ||||||
142 | |||||||
143 | sub render_link { | ||||||
144 | 0 | 0 | 0 | 0 | my ($self, $node) = @_; | ||
145 | 0 | 0 | my ($link, $text) = @{$node}{qw(link text)}; | ||||
0 | 0 | ||||||
146 | 0 | 0 | 0 | $text = $link if not length $text; | |||
147 | 0 | 0 | "$text"; | ||||
148 | } | ||||||
149 | |||||||
150 | sub render_complete { | ||||||
151 | 0 | 0 | 0 | 0 | my ($self, $out) = @_; | ||
152 | 0 | 0 | chomp $out; | ||||
153 | <<"..." | ||||||
154 | |||||||
155 | |||||||
156 | |||||||
157 | |||||||
158 | |
||||||
159 | |||||||
160 | |||||||
161 | |||||||
162 | |
||||||
163 | |||||||
164 | $out | ||||||
165 | |||||||
166 | |||||||
167 | |||||||
168 | |||||||
169 | ... | ||||||
170 | 0 | 0 | } | ||||
171 | |||||||
172 | #------------------------------------------------------------------------------ | ||||||
173 | sub format_phrase_func_html { | ||||||
174 | 17 | 17 | 0 | 53 | my ($self, $tag, $class, $attrib, $content) = @_; | ||
175 | 17 | 41 | my $attribs = ''; | ||||
176 | 17 | 100 | 63 | if (@$class) { | |||
177 | 7 | 31 | $attribs = ' class="' . join(' ', @$class) . '"'; | ||||
178 | } | ||||||
179 | 17 | 100 | 67 | if (@$attrib) { | |||
180 | $attribs = ' ' . join(' ', map { | ||||||
181 | 4 | 100 | 12 | /=".*"$/ ? $_ : do { s/=(.*)/="$1"/; $_ } | |||
4 | 32 | ||||||
2 | 21 | ||||||
2 | 13 | ||||||
182 | } @$attrib); | ||||||
183 | } | ||||||
184 | 17 | 100 | 134 | length($content) | |||
185 | ? "<$tag$attribs>$content$tag>" | ||||||
186 | : "<$tag$attribs/>"; | ||||||
187 | } | ||||||
188 | |||||||
189 | sub phrase_func_bold { | ||||||
190 | 17 | 17 | 0 | 54 | my ($self, $args) = @_; | ||
191 | 17 | 74 | my ($success, $class, $attrib, $content) = | ||||
192 | $self->parse_phrase_func_args_html($args); | ||||||
193 | 17 | 50 | 70 | return unless $success; | |||
194 | 17 | 78 | $self->format_phrase_func_html('strong', $class, $attrib, $content); | ||||
195 | } | ||||||
196 | |||||||
197 | sub parse_phrase_func_args_html { | ||||||
198 | 17 | 17 | 0 | 48 | my ($self, $args) = @_; | ||
199 | 17 | 55 | my ($class, $attrib, $content) = ([], [], ''); | ||||
200 | 17 | 40 | $args =~ s/^ //; | ||||
201 | 17 | 100 | 248 | if ($args =~ /\A((?:\\:|[^\:])*):((?s:.*))\z/) { | |||
202 | 14 | 43 | $attrib = $1; | ||||
203 | 14 | 41 | $content = $2; | ||||
204 | 14 | 47 | $attrib =~ s/\\:/:/g; | ||||
205 | 14 | 73 | ($class, $attrib) = $self->parse_attrib($attrib); | ||||
206 | } | ||||||
207 | else { | ||||||
208 | 3 | 6 | $content = $args; | ||||
209 | } | ||||||
210 | 17 | 77 | return 1, $class, $attrib, $content; | ||||
211 | } | ||||||
212 | |||||||
213 | sub parse_attrib { | ||||||
214 | 14 | 14 | 0 | 34 | my ($self, $text) = @_; | ||
215 | 14 | 46 | my ($class, $attrib) = ([], []); | ||||
216 | 14 | 56 | while (length $text) { | ||||
217 | 14 | 100 | 131 | if ($text =~ s/^\s*(\w[\w\-]*)(?=\s|\z)\s*//) { | |||
100 | |||||||
50 | |||||||
218 | 10 | 45 | push @$class, $1; | ||||
219 | } | ||||||
220 | elsif ($text =~ s/^\s*(\w[\w\-]*="[^"]*")(?=\s|\z)s*//) { | ||||||
221 | 2 | 12 | push @$attrib, $1; | ||||
222 | } | ||||||
223 | elsif ($text =~ s/^\s*(\w[\w\-]*=\S+)(?=\s|\z)s*//) { | ||||||
224 | 2 | 11 | push @$attrib, $1; | ||||
225 | } | ||||||
226 | else { | ||||||
227 | 0 | 0 | last; | ||||
228 | } | ||||||
229 | } | ||||||
230 | 14 | 55 | return $class, $attrib; | ||||
231 | } | ||||||
232 | |||||||
233 | 1; |