File Coverage

blib/lib/Term/Choose/LineFold/PP.pm
Criterion Covered Total %
statement 52 62 83.8
branch 21 28 75.0
condition 11 12 91.6
subroutine 9 9 100.0
pod 0 4 0.0
total 93 115 80.8


line stmt bran cond sub pod time code
1             package Term::Choose::LineFold::PP;
2              
3 5     5   220670 use warnings;
  5         11  
  5         432  
4 5     5   33 use strict;
  5         8  
  5         135  
5 5     5   78 use 5.10.1;
  5         18  
6              
7             our $VERSION = '1.782';
8              
9 5     5   30 use Exporter qw( import );
  5         9  
  5         941  
10              
11             our @EXPORT_OK = qw( char_width print_columns cut_to_printwidth adjust_to_printwidth );
12              
13             BEGIN {
14 5 50   5   34 if ( exists $ENV{TC_AMBIGUOUS_WIDTH_IS_WIDE} ) { # 24.03.2025
15 0 0       0 if ( $ENV{TC_AMBIGUOUS_WIDTH_IS_WIDE} ) {
16 0         0 require Term::Choose::LineFold::PP::CharWidthAmbiguousWide;
17 0         0 Term::Choose::LineFold::PP::CharWidthAmbiguousWide->import( 'table_char_width' );
18             }
19             else {
20 0         0 require Term::Choose::LineFold::PP::CharWidthDefault;
21 0         0 Term::Choose::LineFold::PP::CharWidthDefault->import( 'table_char_width' );
22             }
23             } #
24             else { #
25 5 50       15 if ( $ENV{TC_AMBIGUOUS_WIDE} ) { #
26 0         0 require Term::Choose::LineFold::PP::CharWidthAmbiguousWide; #
27 0         0 Term::Choose::LineFold::PP::CharWidthAmbiguousWide->import( 'table_char_width' ); #
28             } #
29             else { #
30 5         4851 require Term::Choose::LineFold::PP::CharWidthDefault; #
31 5         3413 Term::Choose::LineFold::PP::CharWidthDefault->import( 'table_char_width' ); #
32             } #
33             } #
34             }
35              
36              
37             my $table = table_char_width();
38              
39             my $cache = {};
40              
41              
42             sub char_width {
43             #my $c = $_[0];
44 80     80 0 195665 my $min = 0;
45 80         79 my $mid;
46 80         103 my $max = $#$table;
47 80 100 66     229 if ( $_[0] < $table->[0][0] || $_[0] > $table->[$max][1] ) {
48 30         119 return 1;
49             }
50 50         76 while ( $max >= $min ) {
51 449         491 $mid = int( ( $min + $max ) / 2 );
52 449 100       725 if ( $_[0] > $table->[$mid][1] ) {
    100          
53 205         262 $min = $mid + 1;
54             }
55             elsif ( $_[0] < $table->[$mid][0] ) {
56 194         250 $max = $mid - 1;
57             }
58             else {
59 50         127 return $table->[$mid][2];
60             }
61             }
62 0         0 return 1;
63             }
64              
65              
66             sub print_columns {
67             #my $str = $_[0];
68 12     12 0 2531 my $width = 0;
69 12         33 my $c;
70 12         34 for my $i ( 0 .. ( length( $_[0] ) - 1 ) ) {
71 68         92 $c = ord substr $_[0], $i, 1;
72 68   100     143 $width += ( $cache->{$c} //= char_width( $c ) );
73             }
74 12         17 return $width;
75             }
76              
77              
78             sub cut_to_printwidth {
79             #my ( $str, $avail_width ) = @_;
80 20     20 0 221397 my $str_w = 0;
81 20         45 my $c;
82 20         97 for my $i ( 0 .. ( length( $_[0] ) - 1 ) ) {
83 66         152 $c = ord substr $_[0], $i, 1;
84 66 100 100     268 if ( ( $str_w += ( $cache->{$c} //= char_width( $c ) ) ) > $_[1] ) {
85 20 100       65 if ( ( $str_w - $cache->{$c} ) < $_[1] ) {
86 6 100       35 return substr( $_[0], 0, $i ) . ' ', substr( $_[0], $i ) if wantarray;
87 3         17 return substr( $_[0], 0, $i ) . ' ';
88             }
89 14 100       70 return substr( $_[0], 0, $i ), substr( $_[0], $i ) if wantarray;
90 7         32 return substr( $_[0], 0, $i );
91             }
92             }
93 0 0       0 return $_[0], '' if wantarray;
94 0         0 return $_[0];
95             }
96              
97              
98             sub adjust_to_printwidth {
99             # my ( $str, $width ) = @_;
100 17     17 0 16271 my $str_w = 0;
101 17         35 my $c;
102 17         76 for my $i ( 0 .. ( length( $_[0] ) - 1 ) ) {
103 63         137 $c = ord substr $_[0], $i, 1;
104 63 100 100     231 if ( ( $str_w += ( $cache->{$c} //= char_width( $c ) ) ) > $_[1] ) {
105 10 100       33 if ( ( $str_w - $cache->{$c} ) < $_[1] ) {
106 3         19 return substr( $_[0], 0, $i ) . ' ';
107             }
108 7         32 return substr( $_[0], 0, $i );
109             }
110             }
111 7 50       22 return $_[0] if $str_w == $_[1];
112 7         38 return $_[0] . ' ' x ( $_[1] - $str_w );
113             }
114              
115              
116              
117             1;
118              
119             __END__