blib/lib/DOM/Tiny/Entities.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 20 | 20 | 100.0 |
branch | 6 | 6 | 100.0 |
condition | n/a | ||
subroutine | 6 | 6 | 100.0 |
pod | 2 | 2 | 100.0 |
total | 34 | 34 | 100.0 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package DOM::Tiny::Entities; | ||||||
2 | |||||||
3 | 2 | 2 | 16309 | use strict; | |||
2 | 3 | ||||||
2 | 47 | ||||||
4 | 2 | 2 | 6 | use warnings; | |||
2 | 2 | ||||||
2 | 41 | ||||||
5 | 2 | 2 | 6 | use Exporter 'import'; | |||
2 | 1 | ||||||
2 | 641 | ||||||
6 | |||||||
7 | our $VERSION = '0.003'; | ||||||
8 | |||||||
9 | our @EXPORT_OK = qw(html_escape html_unescape); | ||||||
10 | |||||||
11 | # To generate a new HTML entity table run this command | ||||||
12 | # perl examples/entities.pl | ||||||
13 | my %ENTITIES; | ||||||
14 | for my $line (split "\n", join('', )) { | ||||||
15 | next unless $line =~ /^(\S+)\s+U\+(\S+)(?:\s+U\+(\S+))?/; | ||||||
16 | $ENTITIES{$1} = defined $3 ? (chr(hex $2) . chr(hex $3)) : chr(hex $2); | ||||||
17 | } | ||||||
18 | |||||||
19 | # Characters that should be escaped in HTML/XML | ||||||
20 | my %ESCAPE = ( | ||||||
21 | '&' => '&', | ||||||
22 | '<' => '<', | ||||||
23 | '>' => '>', | ||||||
24 | '"' => '"', | ||||||
25 | '\'' => ''' | ||||||
26 | ); | ||||||
27 | |||||||
28 | sub html_escape { | ||||||
29 | 425 | 425 | 1 | 445 | my $str = shift; | ||
30 | 425 | 532 | $str =~ s/([&<>"'])/$ESCAPE{$1}/ge; | ||||
12 | 28 | ||||||
31 | 425 | 1314 | return $str; | ||||
32 | } | ||||||
33 | |||||||
34 | sub html_unescape { | ||||||
35 | 33935 | 33935 | 1 | 25638 | my $str = shift; | ||
36 | 33935 | 24267 | $str =~ s/&(?:\#((?:[0-9]{1,7}|x[0-9a-fA-F]{1,6}));|(\w+;))/_decode($1, $2)/ge; | ||||
28 | 49 | ||||||
37 | 33935 | 130762 | return $str; | ||||
38 | } | ||||||
39 | |||||||
40 | sub _decode { | ||||||
41 | 28 | 28 | 46 | my ($point, $name) = @_; | |||
42 | |||||||
43 | # Code point | ||||||
44 | 28 | 100 | 91 | return chr($point !~ /^x/ ? $point : hex $point) unless defined $name; | |||
100 | |||||||
45 | |||||||
46 | # Named character reference | ||||||
47 | 19 | 100 | 95 | return exists $ENTITIES{$name} ? $ENTITIES{$name} : "&$name"; | |||
48 | } | ||||||
49 | |||||||
50 | 1; | ||||||
51 | |||||||
52 | =encoding utf8 | ||||||
53 | |||||||
54 | =head1 NAME | ||||||
55 | |||||||
56 | DOM::Tiny::Entities - Escape or unescape HTML entities in strings | ||||||
57 | |||||||
58 | =head1 SYNOPSIS | ||||||
59 | |||||||
60 | use DOM::Tiny::Entities qw(html_escape html_unescape); | ||||||
61 | |||||||
62 | my $str = 'foo & bar'; | ||||||
63 | $str = html_unescape $str; # "foo & bar" | ||||||
64 | $str = html_escape $str; # "foo & bar" | ||||||
65 | |||||||
66 | =head1 DESCRIPTION | ||||||
67 | |||||||
68 | L |
||||||
69 | entities for L |
||||||
70 | are exported on demand. | ||||||
71 | |||||||
72 | =head1 FUNCTIONS | ||||||
73 | |||||||
74 | =head2 html_escape | ||||||
75 | |||||||
76 | my $escaped = html_escape $str; | ||||||
77 | |||||||
78 | Escape unsafe characters C<&>, C<< < >>, C<< > >>, C<">, and C<'> in string. | ||||||
79 | |||||||
80 | html_escape ' '; # "<div>" |
||||||
81 | |||||||
82 | =head2 html_unescape | ||||||
83 | |||||||
84 | my $str = html_unescape $escaped; | ||||||
85 | |||||||
86 | Unescape all HTML entities in string, according to the | ||||||
87 | L. | ||||||
88 | |||||||
89 | html_unescape '<div> # " " |
||||||
90 | |||||||
91 | =head1 BUGS | ||||||
92 | |||||||
93 | Report any issues on the public bugtracker. | ||||||
94 | |||||||
95 | =head1 AUTHOR | ||||||
96 | |||||||
97 | Dan Book |
||||||
98 | |||||||
99 | =head1 COPYRIGHT AND LICENSE | ||||||
100 | |||||||
101 | This software is Copyright (c) 2015 by Dan Book. | ||||||
102 | |||||||
103 | This is free software, licensed under: | ||||||
104 | |||||||
105 | The Artistic License 2.0 (GPL Compatible) | ||||||
106 | |||||||
107 | =head1 SEE ALSO | ||||||
108 | |||||||
109 | L |
||||||
110 | |||||||
111 | =cut | ||||||
112 | |||||||
113 | __DATA__ |