1package XML::Atom::Syndication::Text;
2use strict;
3
4use base qw( XML::Atom::Syndication::Object );
5
6XML::Atom::Syndication::Text->mk_accessors('attribute', 'type');
7
8sub init {
9    my $text = shift;
10    my %param = @_ == 1 ? (Body => $_[0]) : @_;    # escaped text is assumed.
11    $text->SUPER::init(%param);
12    my $e = $text->elem;
13    if ($param{Body}) {
14        $text->body($param{Body});
15    }
16    if ($param{Type}) {
17        $text->type($param{Type});
18    }
19    $text;
20}
21
22sub body {
23    my $text = shift;
24    my $elem = $text->elem;
25    my $type = $elem->attributes->{'{}type'} || 'text';
26    if (@_) {    # set
27        my $data = shift;
28        if ($type eq 'xhtml') {
29            my $node = $data;
30            unless (ref $node) {
31                my $copy =
32                    '<div xmlns="http://www.w3.org/1999/xhtml">' . $data
33                  . '</div>';
34                eval {
35                    require XML::Elemental;
36                    my $parser = XML::Elemental->parser;
37                    my $xml    = $parser->parse_string($copy);
38                    $node = $xml->contents->[0];
39                };
40                return $text->error(
41                                 "Error parsing content body string as XML: $@")
42                  if $@;
43            }
44            $node->parent($elem);
45            $elem->contents([$node]);
46        } else {    # is text or html
47            my $text = XML::Elemental::Characters->new;
48            $text->data($data);
49            $text->parent($elem);
50            $elem->contents([$text]);
51        }
52        $text->{__body} = undef;
53        1;
54    } else {    # get
55        unless (defined $text->{__body}) {
56            if ($type eq 'xhtml') {
57                my @children =
58                  grep { ref($_) eq 'XML::Elemental::Element' }
59                  @{$elem->contents};
60                if (@children) {
61                    my ($local) =
62                      $children[0]->name =~ /{.*}(.+)/;    # process name
63                    @children = @{$children[0]->contents}
64                      if (@children == 1 && $local eq 'div');
65
66                    # $text->{__body} = '<div>';
67                    my $w = XML::Atom::Syndication::Writer->new;
68                    $w->set_prefix('', 'http://www.w3.org/1999/xhtml');
69                    $w->no_cdata(1);  # works nicer with fringe case. see tests.
70                    map { $text->{__body} .= $w->as_xml($_) } @children;
71
72                    # $text->{__body} .= '</div>';
73                } else {
74                    $text->{__body} = $elem->text_content;
75                }
76                if ($] >= 5.008) {
77                    require Encode;
78                    Encode::_utf8_on($text->{__body});
79                    $text->{__body} =~ s/&#x(\w{4});/chr(hex($1))/eg;
80                    Encode::_utf8_off($text->{__body});
81                }
82            } else {    # escaped
83                $text->{__body} = $elem->text_content;
84            }
85        }
86        $text->{__body};
87    }
88}
89
901;
91
92__END__
93
94=begin
95
96=head1 NAME
97
98XML::Atom::Syndication::Text - class representing an Atom
99text construct
100
101=head1 DESCRIPTION
102
103A Text construct contains human-readable text, usually in
104small quantities. Its content (body) is Language-Sensitive.
105
106=head1 METHODS
107
108XML::Atom::Syndication::Text is a subclass of
109L<XML::Atom::Syndication:::Object> that it inherits a number of
110methods from. You should already be familiar with this base
111class before proceeding.
112
113All of these accessors return a string. You can set these elements
114by passing in an optional string.
115
116=over
117
118=item body
119
120An accessor to the text itself.
121
122=item type
123
124The format of the text. The value of type may be one
125"text", "html", or "xhtml". Unlike the type attribute in the
126content element, this attribute MAY NOT be a MIME type. If
127undefined "text" should be assumed.
128
129=back
130
131=head1 AUTHOR & COPYRIGHT
132
133Please see the L<XML::Atom::Syndication> manpage for author,
134copyright, and license information.
135
136=cut
137
138=end
139
140