blib/lib/Text/YAWikiFormater.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 229 | 265 | 86.4 |
branch | 76 | 118 | 64.4 |
condition | 27 | 60 | 45.0 |
subroutine | 17 | 20 | 85.0 |
pod | 7 | 7 | 100.0 |
total | 356 | 470 | 75.7 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package Text::YAWikiFormater; | ||||||
2 | |||||||
3 | 4 | 4 | 275462 | use 5.010; | |||
4 | 45 | ||||||
4 | 4 | 4 | 23 | use strict; | |||
4 | 10 | ||||||
4 | 81 | ||||||
5 | 4 | 4 | 19 | use warnings; | |||
4 | 6 | ||||||
4 | 118 | ||||||
6 | |||||||
7 | 4 | 4 | 2311 | use HTML::Entities qw(encode_entities); | |||
4 | 23921 | ||||||
4 | 335 | ||||||
8 | 4 | 4 | 2796 | use JSON qw(from_json); | |||
4 | 51461 | ||||||
4 | 28 | ||||||
9 | |||||||
10 | our $VERSION = '0.51'; | ||||||
11 | |||||||
12 | my %plugins = ( | ||||||
13 | toc => \&_handle_toc, | ||||||
14 | image => \&_handle_image, | ||||||
15 | |||||||
16 | restore_code_block => \&_restore_code_block, | ||||||
17 | ); | ||||||
18 | |||||||
19 | my %namespaces = ( | ||||||
20 | wp => { prefix => 'http://en.wikipedia.org/', category=>':' }, | ||||||
21 | gs => { prefix => 'http://www.google.com/search?q=' }, | ||||||
22 | ); | ||||||
23 | |||||||
24 | my %closed = ( | ||||||
25 | b => qr{(?:(? | ||||||
26 | i => qr{(? | ||||||
27 | u => qr{__}, | ||||||
28 | del => qr{(? | ||||||
29 | tt => qw{''}, | ||||||
30 | |||||||
31 | heads => [qr[^(?=!{1,6}\s)]msix, qr[$]msix, \&_header_id, undef,"\n"], | ||||||
32 | |||||||
33 | code => [qr[^\{\{\{$]msix,qr[^\}\}\}$]msix, \&_escape_code], | ||||||
34 | |||||||
35 | blockquote => [qr{^>\s}msix, qr{^(?!>)}msix, qr{^>\s}msix, '',"\n"], | ||||||
36 | |||||||
37 | lists => [qr{^(?=[\*\#]+\s)}msix, qr{(?:^(?![\*\#\s])|\z)}msix, \&_do_lists], | ||||||
38 | |||||||
39 | links => [qr{(?=\[\[)}, qr{(?<=\]\])},\&_do_links], | ||||||
40 | links2 => [qr{\s(?=http://)}, qr{\s},\&_do_links], | ||||||
41 | |||||||
42 | br => [qr{^[\n\s]*(?=$)}msix, qr[$]msix, sub { " ",'',''}], |
||||||
43 | |||||||
44 | comments => [qr{/\*}msix, qr{\*/}msix, sub{ '','',''}], | ||||||
45 | ); | ||||||
46 | |||||||
47 | my %nonclosed = ( | ||||||
48 | hr => qr{^[-\*]{3,}\s*?$}msix, | ||||||
49 | ); | ||||||
50 | |||||||
51 | my @do_first = qw( code lists ); | ||||||
52 | # for consistent order | ||||||
53 | my @do_second = qw( b i u del tt heads blockquote links links2 br comments ); | ||||||
54 | |||||||
55 | sub new { | ||||||
56 | 4 | 4 | 1 | 268 | my $class = shift; | ||
57 | |||||||
58 | 4 | 17 | my $self = bless { @_ }, $class; | ||||
59 | |||||||
60 | 4 | 50 | 26 | die "body is a mandatory parameter" unless $self->{body}; | |||
61 | |||||||
62 | 4 | 12 | return $self; | ||||
63 | } | ||||||
64 | |||||||
65 | sub urls { | ||||||
66 | 4 | 4 | 1 | 11 | my $self= shift; | ||
67 | 4 | 9 | my $body = $self->{body}; | ||||
68 | |||||||
69 | 4 | 50 | 13 | return unless $body; | |||
70 | |||||||
71 | 4 | 52 | my @links = $body =~m{(\[\[(?:[^\|\]]*)(?:\|(?:[^\]]+))?\]\])}g; | ||||
72 | 4 | 48 | push @links, $body =~m{\s(https?://\S+)\s}g; | ||||
73 | |||||||
74 | 4 | 50 | 30 | my $links = $self->{_links} ||= {}; | |||
75 | |||||||
76 | LINK: | ||||||
77 | 4 | 12 | for my $lnk ( @links ) { | ||||
78 | 20 | 50 | 47 | next if $links->{$lnk}; | |||
79 | |||||||
80 | 20 | 50 | 83 | my $hlnk = $links->{$lnk} ||= {}; | |||
81 | |||||||
82 | 20 | 100 | 48 | if ($lnk =~ m{\Ahttps?://}) { | |||
83 | 2 | 11 | %$hlnk = ( title => $lnk, href => $lnk, _class => 'external' ); | ||||
84 | 2 | 7 | next LINK; | ||||
85 | } | ||||||
86 | |||||||
87 | 18 | 100 | ($lnk) = $lnk =~ m{\A\[\[\s*(.*)\s*\]\]\z}g; | ||||
88 | 18 | 108 | $lnk=~s{\s*\z}[]g; | ||||
89 | |||||||
90 | 18 | 117 | my ($label,$link) = split qr{\s*\|\s*}, $lnk, 2; | ||||
91 | 18 | 100 | 55 | unless ($link) { | |||
92 | 7 | 13 | $link = $label; | ||||
93 | 7 | 100 | 28 | if ( $link =~ m{.*[\>\:]\s*([^\>]+)\z} ) { | |||
94 | 5 | 13 | $label = $1; | ||||
95 | } | ||||||
96 | } | ||||||
97 | |||||||
98 | 18 | 40 | $hlnk->{title} = $label; | ||||
99 | 18 | 31 | $hlnk->{original_to} = $link; | ||||
100 | 18 | 100 | 38 | if ($link =~ m{\Ahttps?://} ) { | |||
101 | 1 | 3 | $hlnk->{_class} = 'external'; | ||||
102 | 1 | 2 | $hlnk->{href} = $link; | ||||
103 | 1 | 4 | next LINK; | ||||
104 | } | ||||||
105 | |||||||
106 | 17 | 33 | my ($base,$categ) = ('','/'); | ||||
107 | 17 | 100 | 38 | if ( $link =~ m{\A(\w+):} ) { | |||
108 | 2 | 11 | my ($namespace,$lnk) = split qr{:}, $link, 2; | ||||
109 | 2 | 5 | $link = $lnk; | ||||
110 | 2 | 50 | 7 | if ( my $nmsp = $namespaces{ $namespace } ){ | |||
111 | 2 | 50 | 6 | if (ref $nmsp eq 'HASH' ) { | |||
0 | |||||||
112 | 2 | 50 | 10 | $base = $nmsp->{prefix} if $nmsp->{prefix}; | |||
113 | 2 | 50 | 5 | $categ = $nmsp->{category} if $nmsp->{category}; | |||
114 | } elsif (ref $nmsp eq 'CODE') { | ||||||
115 | 0 | 0 | ($base, $categ, $lnk) = $nmsp->($namespace,$link); | ||||
116 | 0 | 0 | 0 | 0 | if ( $lnk and $lnk =~ m{\Ahttps?://} ) { | ||
0 | |||||||
117 | 0 | 0 | $hlnk->{href} = $lnk; | ||||
118 | 0 | 0 | $hlnk->{_class}='external'; | ||||
119 | 0 | 0 | next LINK; | ||||
120 | } elsif ( $lnk ) { | ||||||
121 | 0 | 0 | $link = $lnk; | ||||
122 | } | ||||||
123 | } | ||||||
124 | |||||||
125 | } else { | ||||||
126 | 0 | 0 | warn "Unknow namespace: $namespace on $lnk\n"; | ||||
127 | } | ||||||
128 | } | ||||||
129 | |||||||
130 | 17 | 50 | 35 | if ( $categ ) { | |||
131 | 17 | 45 | $link =~ s{\s*\>\s*}{$categ}g; | ||||
132 | } | ||||||
133 | 17 | 100 | 34 | if ( $base ) { | |||
134 | 2 | 5 | $link = $base.$link; | ||||
135 | } | ||||||
136 | 17 | 100 | 37 | unless ( $link =~ m{\Ahttps?://} ) { | |||
137 | 15 | 34 | $link = urify( $link ); | ||||
138 | } | ||||||
139 | 17 | 44 | $hlnk->{href} = $link; | ||||
140 | } | ||||||
141 | |||||||
142 | 4 | 100 | 17 | return wantarray ? %{$self->{_links}} : $self->{_links}; | |||
1 | 9 | ||||||
143 | } | ||||||
144 | |||||||
145 | sub urify { | ||||||
146 | 21 | 21 | 1 | 37 | my $link = shift; | ||
147 | 21 | 100 | 56 | my $reg = shift || "^\\w\\-\\/\\s\\#"; | |||
148 | |||||||
149 | 21 | 148 | $link =~ s{\s*\z}{}g; | ||||
150 | 21 | 100 | 63 | $link =~ s{\s*>\s*}{/}g unless $link =~ m{/}; | |||
151 | |||||||
152 | 21 | 60 | $link = encode_entities( $link, $reg ); | ||||
153 | 21 | 1606 | $link =~ s{\s+}{-}g; | ||||
154 | 21 | 65 | while (my ($ent)=$link=~/\&(\#?\w+);/) { | ||||
155 | 0 | 0 | 0 | my $ec=$ent=~/(acute|grave|circ|uml|ring|slash|tilde|cedil)$/i? | |||
156 | substr($ent,0,1):'_'; | ||||||
157 | 0 | 0 | $link=~s/\&$ent;/$ec/ig; | ||||
158 | } | ||||||
159 | 21 | 46 | $link="\L$link"; | ||||
160 | 21 | 34 | $link=~s/\_+$//g; | ||||
161 | 21 | 32 | $link=~s/\_+/\_/g; | ||||
162 | |||||||
163 | 21 | 43 | return $link; | ||||
164 | } | ||||||
165 | |||||||
166 | sub set_links { | ||||||
167 | 0 | 0 | 1 | 0 | my ($self, $links) = @_; | ||
168 | |||||||
169 | 0 | 0 | $self->{_links} = $links; | ||||
170 | |||||||
171 | 0 | 0 | return; | ||||
172 | } | ||||||
173 | |||||||
174 | sub format { | ||||||
175 | 3 | 3 | 1 | 14 | my $self = shift; | ||
176 | 3 | 7 | my $body = $self->{body}; | ||||
177 | |||||||
178 | 3 | 8 | delete $self->{__headers}; | ||||
179 | 3 | 5 | delete $self->{__toc}; | ||||
180 | |||||||
181 | 3 | 8 | my %done = (); | ||||
182 | |||||||
183 | 3 | 11 | $self->urls(); | ||||
184 | |||||||
185 | 3 | 6 | $body =~ s{&}{&}g; | ||||
186 | 3 | 8 | $body =~ s{<}{<}g; | ||||
187 | 3 | 14 | $body =~ s{>}{>}g; | ||||
188 | |||||||
189 | # closed tags | ||||||
190 | 3 | 23 | for my $tag ( @do_first, @do_second, keys %closed ) { | ||||
191 | 78 | 100 | 217 | next if $done{ $tag }++; | |||
192 | |||||||
193 | my ($re1, $re2, $re3, $re4, $re5, $re6) | ||||||
194 | = ref $closed{ $tag } eq 'ARRAY' | ||||||
195 | 24 | 72 | ? @{ $closed{ $tag } } | ||||
196 | 39 | 100 | 113 | : ( $closed{ $tag } ); | |||
197 | |||||||
198 | 39 | 100 | 78 | if (!$re2) { | |||
199 | 15 | 22 | my $in = 0; | ||||
200 | 15 | 155 | while ( $body =~ m{$re1}msix ) { | ||||
201 | 10 | 100 | 27 | my $tg = $in ? "$tag>" :"<$tag>"; | |||
202 | 10 | 67 | $body=~s{$re1}{$tg}msix; | ||||
203 | 10 | 124 | $in = 1 - $in; | ||||
204 | } | ||||||
205 | 15 | 50 | 43 | $body.="$tag>" if $in; | |||
206 | } else { | ||||||
207 | 24 | 787 | while ($body =~ m{$re1(.*?)$re2}msix) { | ||||
208 | 43 | 121 | my $in = $1; | ||||
209 | 43 | 107 | my ($t1,$t2) = ("<$tag>","$tag>"); | ||||
210 | 43 | 100 | 121 | if (ref $re3 eq 'Regexp') { | |||
50 | |||||||
211 | 4 | 50 | 12 | $re4 //= ''; | |||
212 | 4 | 42 | $in =~ s{ $re3 }{$re4}msixg; | ||||
213 | } elsif (ref $re3 eq 'CODE') { | ||||||
214 | 39 | 84 | ($t1,$in,$t2) = $re3->($self, $t1, $in, $t2); | ||||
215 | } | ||||||
216 | 43 | 50 | 89 | $t1 //= ''; | |||
217 | 43 | 50 | 74 | $in //= ''; | |||
218 | 43 | 50 | 112 | $t2 //= ''; | |||
219 | 43 | 100 | 92 | $re5 //= ''; | |||
220 | 43 | 1396 | $body =~ s{$re1(.*?)$re2}{$t1$in$t2$re5}smxi; | ||||
221 | } | ||||||
222 | } | ||||||
223 | } | ||||||
224 | |||||||
225 | 3 | 15 | for my $tag ( keys %nonclosed ) { | ||||
226 | 3 | 8 | my ($re1) = ($nonclosed{ $tag } ); | ||||
227 | |||||||
228 | 3 | 59 | $body =~ s{ $re1 }{<$tag />}msixg; | ||||
229 | } | ||||||
230 | |||||||
231 | 3 | 20 | while ($body =~ m[(? | ||||
232 | 2 | 9 | my ($plugin, $params) = ($1,$2); | ||||
233 | 2 | 8 | $params = _parse_plugin_params($params); | ||||
234 | |||||||
235 | 2 | 5 | my $res = ''; | ||||
236 | 2 | 50 | 7 | if ( $plugins{$plugin} ){ | |||
237 | 2 | 50 | 8 | $res = $plugins{ $plugin }->( $self, $plugin, $params ) // ''; | |||
238 | } | ||||||
239 | |||||||
240 | 2 | 33 | $body =~ s[(? | ||||
241 | } | ||||||
242 | |||||||
243 | 3 | 50 | while ($body =~ m[\/\+\+(\w+)(?:[:\s*](.+))?\+\+\/]msix) { | ||||
244 | 1 | 9 | my ($plugin, $params) = ($1,$2); | ||||
245 | 1 | 14 | $params=~s{\A\s*}{}; | ||||
246 | 1 | 8 | my @params = split qr{\s*,\s*}, $params; | ||||
247 | |||||||
248 | 1 | 3 | my $res = ''; | ||||
249 | 1 | 50 | 4 | if ( $plugins{$plugin} ){ | |||
250 | 1 | 50 | 7 | $res = $plugins{ $plugin }->( $self, $plugin, @params ) // ''; | |||
251 | } | ||||||
252 | |||||||
253 | 1 | 38 | $body =~ s[\/\+\+(\w+)(?:[:\s*](.+))?\+\+\/][$res]msix; | ||||
254 | } | ||||||
255 | |||||||
256 | 3 | 16 | return $body; | ||||
257 | } | ||||||
258 | |||||||
259 | sub register_namespace { | ||||||
260 | 0 | 0 | 1 | 0 | my $class = shift; | ||
261 | |||||||
262 | 0 | 0 | my ($namespace, $info, $override) = @_; | ||||
263 | |||||||
264 | $namespaces{ $namespace } = $info | ||||||
265 | 0 | 0 | 0 | 0 | if $override or !$namespaces{ $namespace }; | ||
266 | } | ||||||
267 | |||||||
268 | sub register_plugin { | ||||||
269 | 0 | 0 | 1 | 0 | my $class = shift; | ||
270 | |||||||
271 | 0 | 0 | my ($pluginname, $pluginref, $override) = @_; | ||||
272 | |||||||
273 | $plugins{ $pluginname } = $pluginref | ||||||
274 | 0 | 0 | 0 | 0 | if $override or !$plugins{ $pluginname }; | ||
275 | } | ||||||
276 | |||||||
277 | sub _header_id { | ||||||
278 | 6 | 6 | 10 | my $self = shift; | |||
279 | 6 | 100 | 21 | my $headers = $self->{__headers} ||= {}; | |||
280 | 6 | 100 | 17 | my $headnames = $self->{__headnames} ||= {}; | |||
281 | 6 | 100 | 15 | my $toc = $self->{__toc} ||= []; | |||
282 | 6 | 14 | my ($t1, $in, $t2) = @_; | ||||
283 | |||||||
284 | 6 | 20 | my ($type) = $in =~ m{^(!{1,6})\s}; | ||||
285 | 6 | 21 | $in =~ s{^!*\s}{}; | ||||
286 | |||||||
287 | 6 | 12 | $t1 = 'h'.length($type); | ||||
288 | 6 | 13 | $t2 = "$t1>"; | ||||
289 | 6 | 9 | $t1 = "<$t1>"; | ||||
290 | |||||||
291 | 6 | 12 | my $id = urify($in, "^\\w\\-\\s"); | ||||
292 | |||||||
293 | 6 | 50 | 17 | if ($headers->{$id}) { | |||
294 | 0 | 0 | my $cnt = 1; | ||||
295 | 0 | 0 | $cnt++ while $headers->{"${id}_$cnt"}; | ||||
296 | 0 | 0 | $id .= "_$cnt"; | ||||
297 | } | ||||||
298 | |||||||
299 | 6 | 14 | $headnames->{$id} = $in; | ||||
300 | 6 | 15 | $headers->{$id} = substr($t1, 2, 1); | ||||
301 | 6 | 14 | push @$toc, $id; | ||||
302 | |||||||
303 | 6 | 17 | substr($t1, -1, 0, " id='$id'"); | ||||
304 | |||||||
305 | 6 | 19 | return $t1, $in, $t2; | ||||
306 | } | ||||||
307 | |||||||
308 | sub _escape_code { | ||||||
309 | 1 | 1 | 2 | my $self = shift; | |||
310 | |||||||
311 | 1 | 4 | my ($t1, $in, $t2) = @_; | ||||
312 | |||||||
313 | 1 | 6 | $in=~s{\n}{ \n}gs; |
||||
314 | |||||||
315 | 1 | 4 | $self->{__codecnt}++; | ||||
316 | 1 | 4 | $self->{__codeblock}->{$self->{__codecnt}} = $in; | ||||
317 | |||||||
318 | 1 | 5 | return '',"/++restore_code_block: $self->{__codecnt}++/", ''; | ||||
319 | } | ||||||
320 | |||||||
321 | sub _do_lists { | ||||||
322 | 2 | 2 | 5 | my $self = shift; | |||
323 | |||||||
324 | 2 | 6 | my ($t1, $in, $t2) = @_; | ||||
325 | |||||||
326 | 2 | 16 | my @lines = split qr{\n}ms, $in; | ||||
327 | 2 | 6 | $in = ''; | ||||
328 | 2 | 4 | my $cl = ''; | ||||
329 | 2 | 3 | my $item; | ||||
330 | 2 | 6 | for my $ln (@lines) { | ||||
331 | 12 | 50 | 30 | if ( $ln !~ m{^\s} ) { | |||
332 | 12 | 100 | 24 | if ($item) { | |||
333 | 10 | 21 | $in .= " |
||||
334 | 10 | 14 | $item = ''; | ||||
335 | } | ||||||
336 | 12 | 45 | my ($nl,$l) = $ln =~ m{^([\*\#]+)\s+(.*)$}; | ||||
337 | 12 | 20 | $ln = $l; | ||||
338 | 12 | 18 | my $close = ''; | ||||
339 | 12 | 16 | my $start = -1; | ||||
340 | 12 | 100 | 24 | if ($nl ne $cl) { | |||
341 | 11 | 25 | for my $i (0..length($cl)-1) { | ||||
342 | 23 | 100 | 100 | 74 | next if !$close and substr($cl,$i,1) eq substr($nl, $i, 1); | ||
343 | 4 | 100 | 12 | $start = $i unless $close; | |||
344 | 4 | 100 | 12 | $close = (substr($cl,$i,1) eq '#' ? "" : "").$close; | |||
345 | } | ||||||
346 | 11 | 100 | 23 | $start = length($cl) if $start == -1; | |||
347 | 11 | 100 | 22 | $in.=$close."\n" if $close; | |||
348 | 11 | 21 | for my $i ($start..length($nl)-1) { | ||||
349 | 11 | 100 | 43 | $in.= substr($nl, $i, 1) eq '#'?"
|
|||
350 | } | ||||||
351 | 11 | 19 | $cl = $nl; | ||||
352 | } | ||||||
353 | } | ||||||
354 | 12 | 22 | $item .= $ln; | ||||
355 | } | ||||||
356 | 2 | 50 | 6 | if ($item) { | |||
357 | 2 | 5 | $in .= " |
||||
358 | } | ||||||
359 | 2 | 50 | 5 | if ($cl) { | |||
360 | 2 | 7 | for my $i (reverse 0..length($cl)-1) { | ||||
361 | 7 | 50 | 16 | $in.=substr($cl,$i,1) eq '#' ? "" : ""; | |||
362 | } | ||||||
363 | 2 | 4 | $in.="\n"; | ||||
364 | } | ||||||
365 | |||||||
366 | 2 | 9 | return '',$in,''; | ||||
367 | } | ||||||
368 | |||||||
369 | sub _do_links { | ||||||
370 | 11 | 11 | 14 | my $self = shift; | |||
371 | |||||||
372 | 11 | 24 | my (undef, $link, undef) = @_; | ||||
373 | |||||||
374 | 11 | 23 | $link =~s{\>}[>]g; | ||||
375 | |||||||
376 | 11 | 50 | 33 | 45 | $self->urls() unless $self->{_links} and $self->{_links}->{$link}; | ||
377 | |||||||
378 | 11 | 50 | 39 | my $lnk = $self->{_links}->{$link} || {}; | |||
379 | |||||||
380 | 11 | 19 | my ($t1,$t2) = ('',''); | ||||
381 | |||||||
382 | 11 | 23 | $t1 = " | ||||
383 | 11 | 100 | 42 | my $class = $lnk->{class} || $lnk->{_class} || ''; | |||
384 | 11 | 100 | 38 | if ( $class ) { | |||
385 | 1 | 4 | $t1.=" class='$class'"; | ||||
386 | } | ||||||
387 | 11 | 20 | $t1.='>'; | ||||
388 | |||||||
389 | 11 | 34 | return $t1, $lnk->{title}, $t2; | ||||
390 | } | ||||||
391 | |||||||
392 | sub _handle_toc { | ||||||
393 | 1 | 1 | 2 | my ($self) = shift; | |||
394 | |||||||
395 | 1 | 3 | my $toc = $self->{__toc}; | ||||
396 | 1 | 3 | my $headers = $self->{__headers}; | ||||
397 | 1 | 3 | my $headnames = $self->{__headnames}; | ||||
398 | |||||||
399 | 1 | 2 | my $res = "\n"; | ||||
400 | 1 | 4 | for my $head (@$toc) { | ||||
401 | 6 | 15 | $res.='*'x$headers->{$head}; | ||||
402 | |||||||
403 | 6 | 8 | $res.=' '; | ||||
404 | 6 | 14 | $res.='[['.$headnames->{$head}.'|#'.$head."]]\n"; | ||||
405 | } | ||||||
406 | 1 | 5 | $res.="\n"; | ||||
407 | |||||||
408 | 1 | 5 | my $wf = (ref $self)->new(body => $res); | ||||
409 | 1 | 10 | $res = $wf->format(); | ||||
410 | |||||||
411 | 1 | 5 | $res = " $res "; |
||||
412 | |||||||
413 | 1 | 15 | return $res; | ||||
414 | } | ||||||
415 | |||||||
416 | sub _handle_image { | ||||||
417 | 1 | 1 | 4 | my ($self, $plugin, $params) = @_; | |||
418 | 1 | 2 | my $src; | ||||
419 | |||||||
420 | 1 | 50 | 5 | if (ref $params eq 'ARRAY') { | |||
421 | 1 | 2 | $src = shift @$params; | ||||
422 | 1 | 50 | 33 | 5 | if (@$params and ref $params->[0] eq 'HASH') { | ||
423 | 0 | 0 | $params = $params->[0]; | ||||
424 | } else { | ||||||
425 | 1 | 3 | $params = { @$params }; | ||||
426 | } | ||||||
427 | } else { | ||||||
428 | 0 | 0 | $src = delete $params->{src}; | ||||
429 | } | ||||||
430 | |||||||
431 | 1 | 50 | 7 | return '' unless $src; | |||
432 | |||||||
433 | 1 | 50 | 33 | 10 | if ($src =~ m{\Ahttps?://} and $self->{image_filter}) { | ||
50 | |||||||
434 | 0 | 0 | $src = $self->{image_filter}->($src, $params); | ||||
435 | } elsif ($self->{image_mapper}) { | ||||||
436 | 0 | 0 | $src = $self->{image_mapper}->($src, $params); | ||||
437 | } | ||||||
438 | |||||||
439 | 1 | 50 | 4 | return '' unless $src; | |||
440 | |||||||
441 | 1 | 6 | my $res = " | ||||
442 | 1 | 50 | 4 | if ( $params->{size} ) { | |||
443 | 0 | 0 | my ($w,$h) = $params->{size} =~ m{\A\d+x\d+\z}; | ||||
444 | |||||||
445 | 0 | 0 | 0 | 0 | if ($w and $h) { | ||
446 | 0 | 0 | 0 | $params->{width} ||= $w; | |||
447 | 0 | 0 | 0 | $params->{height} ||= $h; | |||
448 | 0 | 0 | delete $params->{size}; | ||||
449 | } | ||||||
450 | } | ||||||
451 | 1 | 15 | for my $attr ( qw(alt title heigth width) ) { | ||||
452 | 4 | 50 | 14 | next unless $params->{ $attr }; | |||
453 | 0 | 0 | my $av = $params->{ $attr }; | ||||
454 | 0 | 0 | $av =~ s{&}{&}g; | ||||
455 | 0 | 0 | $av =~ s{<}{>}g; | ||||
456 | 0 | 0 | $av =~ s{>}{<}g; | ||||
457 | 0 | 0 | $av =~ s{'}{'}g; | ||||
458 | 0 | 0 | $res.=" $attr='$av'"; | ||||
459 | } | ||||||
460 | |||||||
461 | 1 | 3 | $res.=' />'; | ||||
462 | |||||||
463 | #MAYBETODO: support for caption, to allow to frame the images | ||||||
464 | # and add a legend under the image. | ||||||
465 | |||||||
466 | 1 | 4 | return $res; | ||||
467 | } | ||||||
468 | |||||||
469 | sub _restore_code_block { | ||||||
470 | 1 | 1 | 3 | my ($self, $plugin, $block) = @_; | |||
471 | |||||||
472 | 1 | 3 | my $res = $self->{__codeblock}->{$block}; | ||||
473 | |||||||
474 | 1 | 6 | return "$res "; |
||||
475 | } | ||||||
476 | |||||||
477 | sub _parse_plugin_params { | ||||||
478 | 2 | 2 | 4 | my $paramstr = shift; | |||
479 | |||||||
480 | 2 | 100 | 6 | return [] unless $paramstr; | |||
481 | |||||||
482 | 1 | 50 | 10 | unless ($paramstr =~ m(\A\s*[\{\[]) ) { | |||
483 | 1 | 4 | $paramstr = '['.$paramstr.']'; | ||||
484 | } | ||||||
485 | |||||||
486 | 1 | 50 | 2 | my $params = eval { | |||
487 | 1 | 9 | from_json( $paramstr, { utf8 => 1 }) | ||||
488 | } or do print STDERR "Error Parsing params: $paramstr ==> $@\n"; | ||||||
489 | #MAYBETODO: export this error somehow? silent it? | ||||||
490 | # exporting it may be useful - specially while previewing | ||||||
491 | # the result. | ||||||
492 | |||||||
493 | 1 | 57 | return $params; | ||||
494 | } | ||||||
495 | |||||||
496 | 1; | ||||||
497 | __END__ |