1package Term::Table::Cell;
2use strict;
3use warnings;
4
5our $VERSION = '0.018';
6
7use Term::Table::LineBreak();
8use Term::Table::Util qw/uni_length/;
9
10use List::Util qw/sum/;
11
12use Term::Table::HashBase qw/value border_left border_right _break _widths border_color value_color reset_color/;
13
14my %CHAR_MAP = (
15    # Special case, \n should render as \n, but also actually do the newline thing
16    "\n" => "\\n\n",
17
18    "\a" => '\\a',
19    "\b" => '\\b',
20    "\e" => '\\e',
21    "\f" => '\\f',
22    "\r" => '\\r',
23    "\t" => '\\t',
24    " "  => ' ',
25);
26
27sub init {
28    my $self = shift;
29
30    # Stringify
31    $self->{+VALUE} = defined $self->{+VALUE} ? "$self->{+VALUE}" : '';
32}
33
34sub char_id {
35    my $class = shift;
36    my ($char) = @_;
37    return "\\N{U+" . sprintf("\%X", ord($char)) . "}";
38}
39
40sub show_char {
41    my $class = shift;
42    my ($char, %props) = @_;
43    return $char if $props{no_newline} && $char eq "\n";
44    return $CHAR_MAP{$char} || $class->char_id($char);
45}
46
47sub sanitize {
48    my $self = shift;
49    $self->{+VALUE} =~ s/([\s\t\p{Zl}\p{C}\p{Zp}])/$self->show_char($1)/ge; # All whitespace except normal space
50}
51
52sub mark_tail {
53    my $self = shift;
54    $self->{+VALUE} =~ s/([\s\t\p{Zl}\p{C}\p{Zp}])$/$1 eq ' ' ? $self->char_id($1) : $self->show_char($1, no_newline => 1)/se;
55}
56
57sub value_width {
58    my $self = shift;
59
60    my $w = $self->{+_WIDTHS} ||= {};
61    return $w->{value} if defined $w->{value};
62
63    my @parts = split /(\n)/, $self->{+VALUE};
64
65    my $max = 0;
66    while (@parts) {
67        my $text = shift @parts;
68        my $sep  = shift @parts || '';
69        my $len = uni_length("$text");
70        $max = $len if $len > $max;
71    }
72
73    return $w->{value} = $max;
74}
75
76sub border_left_width {
77    my $self = shift;
78    $self->{+_WIDTHS}->{left} ||= uni_length($self->{+BORDER_LEFT} || '');
79}
80
81sub border_right_width {
82    my $self = shift;
83    $self->{+_WIDTHS}->{right} ||= uni_length($self->{+BORDER_RIGHT} || '');
84}
85
86sub width {
87    my $self = shift;
88    $self->{+_WIDTHS}->{all} ||= sum(map { $self->$_ } qw/value_width border_left_width border_right_width/);
89}
90
91sub break {
92    my $self = shift;
93    $self->{+_BREAK} ||= Term::Table::LineBreak->new(string => $self->{+VALUE});
94}
95
96sub reset {
97    my $self = shift;
98    delete $self->{+_BREAK};
99}
100
1011;
102
103__END__
104
105=pod
106
107=encoding UTF-8
108
109=head1 NAME
110
111Term::Table::Cell - Representation of a cell in a table.
112
113=head1 DESCRIPTION
114
115This package is used to represent a cell in a table.
116
117=head1 SOURCE
118
119The source code repository for Term-Table can be found at
120F<http://github.com/exodist/Term-Table/>.
121
122=head1 MAINTAINERS
123
124=over 4
125
126=item Chad Granum E<lt>exodist@cpan.orgE<gt>
127
128=back
129
130=head1 AUTHORS
131
132=over 4
133
134=item Chad Granum E<lt>exodist@cpan.orgE<gt>
135
136=back
137
138=head1 COPYRIGHT
139
140Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
141
142This program is free software; you can redistribute it and/or
143modify it under the same terms as Perl itself.
144
145See F<http://dev.perl.org/licenses/>
146
147=cut
148