File Coverage

blib/lib/Unicode/Block/Ascii.pm
Criterion Covered Total %
statement 37 77 48.0
branch 4 24 16.6
condition 1 3 33.3
subroutine 9 9 100.0
pod 1 1 100.0
total 52 114 45.6


line stmt bran cond sub pod time code
1             package Unicode::Block::Ascii;
2              
3 5     5   611595 use base qw(Unicode::Block);
  5         13  
  5         3092  
4 5     5   274839 use strict;
  5         11  
  5         131  
5 5     5   27 use warnings;
  5         12  
  5         353  
6              
7 5     5   31 use Error::Pure qw(err);
  5         10  
  5         316  
8 5     5   27 use Readonly;
  5         9  
  5         209  
9 5     5   2816 use Text::UnicodeBox;
  5         2962846  
  5         314  
10 5     5   50 use Text::UnicodeBox::Control qw(:all);
  5         13  
  5         6557  
11              
12             # Constants.
13             Readonly::Scalar our $SPACE => q{ };
14              
15             our $VERSION = 0.05;
16              
17             # Get output.
18             sub get {
19 1     1 1 234054 my $self = shift;
20              
21             # Get width.
22 1         7 $self->_get_chars;
23             $self->{'_width'} = 16 + $self->{'_base_width'}
24 1         6 + (16 * $self->{'_char_width'});
25              
26             # Check width.
27 1 50 33     12 if (defined $self->{'title'}
28             && (length $self->{'title'}) > $self->{'_width'}) {
29              
30 1         7 err 'Long title.';
31             }
32              
33             # Box objext.
34 0         0 my $box = Text::UnicodeBox->new;
35              
36             # Title.
37 0 0       0 if (defined $self->{'title'}) {
38              
39             # Compute title.
40 0         0 my $spaces = $self->{'_width'} - length $self->{'title'};
41 0         0 my $left = int($spaces / 2);
42 0         0 my $right = $self->{'_width'} - $left - length $self->{'title'};
43 0         0 my $title = ($SPACE x $left).$self->{'title'}.($SPACE x $right);
44              
45             # Add title.
46 0         0 $box->add_line(
47             BOX_START('top' => 'light', 'bottom' => 'light'),
48             $title,
49             BOX_END(),
50             );
51             }
52              
53             # Header.
54 0         0 my @headers = $SPACE x $self->{'_base_width'}, BOX_RULE;
55 0         0 foreach my $header_char (0 .. 9, 'A' .. 'F') {
56 0 0       0 if (@headers) {
57 0         0 push @headers, BOX_RULE;
58             }
59 0         0 my $table_header_char = $header_char;
60 0 0       0 if ($self->{'_char_width'} > 1) {
61             $table_header_char
62 0         0 = ($SPACE x ($self->{'_char_width'} - 1)).
63             $header_char;
64             }
65 0         0 push @headers, $table_header_char;
66             }
67 0         0 my @title;
68 0 0       0 if (! defined $self->{'title'}) {
69 0         0 @title = ('top' => 'light');
70             }
71             $box->add_line(
72 0         0 BOX_START(@title, 'bottom' => 'light'), @headers, BOX_END(),
73             );
74              
75             # Columns.
76 0         0 my @cols;
77 0         0 foreach my $item (@{$self->{'_chars'}}) {
  0         0  
78 0 0       0 if (@cols) {
79 0         0 push @cols, BOX_RULE;
80             } else {
81 0         0 push @cols, $SPACE.$item->base.$SPACE, BOX_RULE;
82 0         0 my $last_num = hex $item->last_hex;
83 0 0       0 if ($last_num > 0) {
84 0         0 push @cols, ($SPACE, BOX_RULE) x $last_num;
85             }
86             }
87 0         0 my $char = $item->char;
88 0 0       0 if ($item->width < $self->{'_char_width'}) {
89 0         0 $char = ($SPACE x ($self->{'_char_width'}
90             - $item->width)).$char;
91             }
92 0         0 push @cols, $char;
93 0 0       0 if ($item->last_hex eq 'f') {
94 0         0 $box->add_line(
95             BOX_START('bottom' => 'light'),
96             @cols,
97             BOX_END(),
98             );
99 0         0 @cols = ();
100             }
101             }
102 0 0       0 if (@cols) {
103 0         0 my $spaces = @cols / 2;
104 0         0 $box->add_line(
105             BOX_START('bottom' => 'light'),
106             @cols, BOX_RULE,
107             ($SPACE, BOX_RULE) x (16 - $spaces),
108             $SPACE,
109             BOX_END,
110             );
111             }
112 0         0 return $box->render;
113             }
114              
115             # Get chars and compute char width.
116             sub _get_chars {
117 1     1   3 my $self = shift;
118 1         4 $self->{'_chars'} = [];
119 1         3 $self->{'_char_width'} = 1;
120 1         5 $self->{'_base_width'} = 0;
121 1         11 while (my $item = $self->next) {
122              
123             # Look for maximal character width in table.
124 128 50       9968 if ($item->width > $self->{'_char_width'}) {
125 0         0 $self->{'_char_width'} = $item->width;
126             }
127              
128             # Look for maximal base length in table.
129 128 100       6033 if ((length $item->base) + 2 > $self->{'_base_width'}) {
130 1         25 $self->{'_base_width'} = (length $item->base) + 2;
131             }
132              
133             # Add character.
134 128         1804 push @{$self->{'_chars'}}, $item;
  128         495  
135             }
136 1         17 return;
137             }
138              
139             1;
140              
141             __END__
142              
143             =pod
144              
145             =encoding utf8
146              
147             =head1 NAME
148              
149             Unicode::Block::Ascii - Ascii output of unicode block.
150              
151             =head1 SYNOPSIS
152              
153             use Unicode::Block::Ascii;
154              
155             my $obj = Unicode::Block::Ascii->new(%parameters);
156             my $output = $obj->get;
157             my $item = $obj->next;
158              
159             =head1 METHODS
160              
161             =head2 C<new>
162              
163             my $obj = Unicode::Block::Ascii->new(%parameters);
164              
165             Constructor.
166              
167             =over 8
168              
169             =item * C<char_from>
170              
171             Character from.
172              
173             Default value is '0000'.
174              
175             =item * C<char_to>
176              
177             Character to.
178              
179             Default value is '007f'.
180              
181             =item * C<title>
182              
183             Title of block.
184              
185             Default value is undef.
186              
187             =back
188              
189             Returns instance of object.
190              
191             =head2 C<get>
192              
193             my $output = $obj->get;
194              
195             Get output.
196              
197             Return string with ascii table of Unicode::Block object.
198              
199             =head2 C<next>
200              
201             my $item = $obj->next;
202              
203             Get next character.
204              
205             Returns Unicode::Block::Item object for character, if character exists.
206             Returns undef, if character doesn't exist.
207              
208             =head1 ERRORS
209              
210             new():
211             From Class::Utils::set_params_pub():
212             Unknown parameter '%s'.
213              
214             get():
215             Long title.
216              
217             =head1 EXAMPLE1
218              
219             =for comment filename=print_unicode_block.pl
220              
221             use strict;
222             use warnings;
223              
224             use Encode qw(encode_utf8);
225             use Unicode::Block::Ascii;
226             use Unicode::Block::List;
227              
228             # Arguments.
229             if (@ARGV < 1) {
230             print STDERR "Usage: $0 block_name\n";
231             exit 1;
232             }
233             my $block_name = $ARGV[0];
234              
235             # List object.
236             my $obj = Unicode::Block::List->new;
237              
238             # Get Unicode::Block for block name.
239             my $block = $obj->block($block_name);
240              
241             # Get ASCII object.
242             my $block_ascii = Unicode::Block::Ascii->new(%{$block});
243              
244             # Print to output.
245             print encode_utf8($block_ascii->get)."\n";
246            
247             # Output:
248             # Usage: /tmp/o1NG0vm_Wf block_name
249              
250             # Output with 'Block Elements' argument:
251             # ┌────────────────────────────────────────┐
252             # │ Block Elements │
253             # ├────────┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┤
254             # │ │0│1│2│3│4│5│6│7│8│9│A│B│C│D│E│F│
255             # ├────────┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
256             # │ U+258x │▀│▁│▂│▃│▄│▅│▆│▇│█│▉│▊│▋│▌│▍│▎│▏│
257             # ├────────┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
258             # │ U+259x │▐│░│▒│▓│▔│▕│▖│▗│▘│▙│▚│▛│▜│▝│▞│▟│
259             # └────────┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
260              
261             =head1 EXAMPLE2
262              
263             =for comment filename=print_unicode_block_in_curses_ui.pl
264              
265             use strict;
266             use warnings;
267            
268             use Curses::UI;
269             use Encode qw(encode_utf8);
270             use Unicode::Block::Ascii;
271             use Unicode::Block::List;
272            
273             # Get unicode block list.
274             my $list = Unicode::Block::List->new;
275             my @unicode_block_list = $list->list;
276            
277             # Window.
278             my $cui = Curses::UI->new;
279             my $win = $cui->add('window_id', 'Window');
280             $win->set_binding(\&exit, "\cQ", "\cC");
281            
282             # Popup menu.
283             my $popupbox = $win->add(
284             'mypopupbox', 'Popupmenu',
285             '-labels' => {
286             map { $_, $_ } @unicode_block_list,
287             },
288             '-onchange' => sub {
289             my $self = shift;
290             $cui->leave_curses;
291             my $block = $list->block($self->get);
292             my $block_ascii = Unicode::Block::Ascii->new(%{$block});
293             print encode_utf8($block_ascii->get)."\n";
294             exit 0;
295             },
296             '-values' => \@unicode_block_list,
297             );
298             $popupbox->focus;
299            
300             # Loop.
301             $cui->mainloop;
302              
303             # Output after select 'Geometric Shapes' item:
304             # ┌────────────────────────────────────────────────────────┐
305             # │ Geometric Shapes │
306             # ├────────┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┤
307             # │ │ 0│ 1│ 2│ 3│ 4│ 5│ 6│ 7│ 8│ 9│ A│ B│ C│ D│ E│ F│
308             # ├────────┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
309             # │ U+25ax │ ■│ □│ ▢│ ▣│ ▤│ ▥│ ▦│ ▧│ ▨│ ▩│ ▪│ ▫│ ▬│ ▭│ ▮│ ▯│
310             # ├────────┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
311             # │ U+25bx │ ▰│ ▱│ ▲│ △│ ▴│ ▵│ ▶│ ▷│ ▸│ ▹│ ►│ ▻│ ▼│ ▽│ ▾│ ▿│
312             # ├────────┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
313             # │ U+25cx │ ◀│ ◁│ ◂│ ◃│ ◄│ ◅│ ◆│ ◇│ ◈│ ◉│ ◊│ ○│ ◌│ ◍│ ◎│ ●│
314             # ├────────┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
315             # │ U+25dx │ ◐│ ◑│ ◒│ ◓│ ◔│ ◕│ ◖│ ◗│ ◘│ ◙│ ◚│ ◛│ ◜│ ◝│ ◞│ ◟│
316             # ├────────┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
317             # │ U+25ex │ ◠│ ◡│ ◢│ ◣│ ◤│ ◥│ ◦│ ◧│ ◨│ ◩│ ◪│ ◫│ ◬│ ◭│ ◮│ ◯│
318             # ├────────┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
319             # │ U+25fx │ ◰│ ◱│ ◲│ ◳│ ◴│ ◵│ ◶│ ◷│ ◸│ ◹│ ◺│ ◻│ ◼│◽│◾│ ◿│
320             # └────────┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
321              
322             =head1 DEPENDENCIES
323              
324             L<Error::Pure>,
325             L<Readonly>,
326             L<Text::UnicodeBox>,
327             L<Text::UnicodeBox::Control>,
328             L<Unicode::Block>.
329              
330             =head1 REPOSITORY
331              
332             L<https://github.com/michal-josef-spacek/Unicode-Block-Ascii>
333              
334             =head1 AUTHOR
335              
336             Michal Josef Špaček L<mailto:skim@cpan.org>
337              
338             L<http://skim.cz>
339              
340             =head1 LICENSE AND COPYRIGHT
341              
342             © 2013-2023 Michal Josef Špaček
343              
344             BSD 2-Clause License
345              
346             =head1 VERSION
347              
348             0.05
349              
350             =cut