| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Text::Table::HTML::DataTables; |
|
2
|
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
392200
|
use 5.010001; |
|
|
1
|
|
|
|
|
2
|
|
|
4
|
1
|
|
|
1
|
|
9
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
37
|
|
|
5
|
1
|
|
|
1
|
|
6
|
use warnings; |
|
|
1
|
|
|
|
|
5
|
|
|
|
1
|
|
|
|
|
980
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY |
|
8
|
|
|
|
|
|
|
our $DATE = '2025-05-15'; # DATE |
|
9
|
|
|
|
|
|
|
our $DIST = 'Text-Table-HTML-DataTables'; # DIST |
|
10
|
|
|
|
|
|
|
our $VERSION = '0.013'; # VERSION |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
sub _encode { |
|
13
|
0
|
|
|
0
|
|
|
state $load = do { require HTML::Entities }; |
|
|
0
|
|
|
|
|
|
|
|
14
|
0
|
|
|
|
|
|
my $val = shift; |
|
15
|
|
|
|
|
|
|
# encode_entities change 0 (false) to empty string so we need to filter the |
|
16
|
|
|
|
|
|
|
# value first |
|
17
|
0
|
0
|
|
|
|
|
if (!defined $val) { |
|
|
|
0
|
|
|
|
|
|
|
18
|
0
|
|
|
|
|
|
""; |
|
19
|
|
|
|
|
|
|
} elsif (!$val) { |
|
20
|
0
|
|
|
|
|
|
"$val"; |
|
21
|
|
|
|
|
|
|
} else { |
|
22
|
0
|
|
|
|
|
|
HTML::Entities::encode_entities($val); |
|
23
|
|
|
|
|
|
|
} |
|
24
|
|
|
|
|
|
|
} |
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub _escape_uri { |
|
27
|
0
|
|
|
0
|
|
|
require URI::Escape; |
|
28
|
0
|
|
|
|
|
|
URI::Escape::uri_escape(shift, "^A-Za-z0-9\-\._~/:"); # : for drive notation on Windows |
|
29
|
|
|
|
|
|
|
} |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub table { |
|
32
|
0
|
|
|
0
|
1
|
|
require HTML::Entities; |
|
33
|
0
|
|
|
|
|
|
require JSON::PP; |
|
34
|
|
|
|
|
|
|
|
|
35
|
0
|
|
|
|
|
|
my %params = @_; |
|
36
|
0
|
0
|
|
|
|
|
my $rows = $params{rows} or die "Must provide rows!"; |
|
37
|
0
|
|
0
|
|
|
|
my $default_length = int($params{default_length} // 1000); |
|
38
|
|
|
|
|
|
|
my $library_link_mode = $params{library_link_mode} // |
|
39
|
0
|
|
0
|
|
|
|
$ENV{PERL_TEXT_TABLE_HTML_DATATABLES_OPT_LIBRARY_LINK_MODE} // 'local'; |
|
|
|
|
0
|
|
|
|
|
|
40
|
|
|
|
|
|
|
|
|
41
|
0
|
|
|
|
|
|
my $max_index = _max_array_index($rows); |
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
# here we go... |
|
44
|
0
|
|
|
|
|
|
my @table; |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
# load css/js |
|
47
|
0
|
|
|
|
|
|
push @table, "\n"; |
|
48
|
0
|
|
|
|
|
|
push @table, "\n"; |
|
49
|
|
|
|
|
|
|
|
|
50
|
0
|
0
|
|
|
|
|
push @table, qq().HTML::Entities::encode_entities($params{caption}).qq(\n) if defined $params{caption}; |
|
51
|
|
|
|
|
|
|
|
|
52
|
0
|
|
|
|
|
|
my $jquery_ver = '2.2.4'; |
|
53
|
0
|
|
|
|
|
|
my $datatables_ver = '1.10.22'; |
|
54
|
0
|
0
|
|
|
|
|
if ($library_link_mode eq 'embed') { |
|
|
|
0
|
|
|
|
|
|
|
55
|
0
|
|
|
|
|
|
require File::ShareDir; |
|
56
|
0
|
|
|
|
|
|
require File::Slurper; |
|
57
|
0
|
|
|
|
|
|
my $dist_dir = File::ShareDir::dist_dir('Text-Table-HTML-DataTables'); |
|
58
|
0
|
|
|
|
|
|
my $path; |
|
59
|
|
|
|
|
|
|
|
|
60
|
0
|
|
|
|
|
|
$path = "$dist_dir/datatables-$datatables_ver/datatables.css"; |
|
61
|
0
|
0
|
|
|
|
|
-r $path or die "Can't embed $path: $!"; |
|
62
|
0
|
|
|
|
|
|
push @table, "\n\n\n"; |
|
63
|
|
|
|
|
|
|
|
|
64
|
0
|
|
|
|
|
|
$path = "$dist_dir/jquery-$jquery_ver/jquery-$jquery_ver.min.js"; |
|
65
|
0
|
0
|
|
|
|
|
-r $path or die "Can't embed $path: $!"; |
|
66
|
0
|
|
|
|
|
|
push @table, "\n\n\n"; |
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
|
|
69
|
0
|
|
|
|
|
|
$path = "$dist_dir/datatables-$datatables_ver/datatables.js"; |
|
70
|
0
|
0
|
|
|
|
|
-r $path or die "Can't embed $path: $!"; |
|
71
|
0
|
|
|
|
|
|
push @table, "\n\n\n"; |
|
72
|
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
} elsif ($library_link_mode eq 'local') { |
|
74
|
0
|
|
|
|
|
|
require File::ShareDir; |
|
75
|
0
|
|
|
|
|
|
my $dist_dir = File::ShareDir::dist_dir('Text-Table-HTML-DataTables'); |
|
76
|
0
|
0
|
|
|
|
|
$dist_dir =~ s!\\!/!g if $^O eq 'MSWin32'; |
|
77
|
0
|
|
|
|
|
|
push @table, qq(\n); |
|
78
|
0
|
|
|
|
|
|
push @table, qq(\n); |
|
79
|
0
|
|
|
|
|
|
push @table, qq(\n); |
|
80
|
|
|
|
|
|
|
} else { |
|
81
|
0
|
|
|
|
|
|
die "Unknown value for the 'library_link_mode' option: '$library_link_mode', please use one of local|embed"; |
|
82
|
|
|
|
|
|
|
} |
|
83
|
|
|
|
|
|
|
|
|
84
|
0
|
|
|
|
|
|
push @table, ''."\n\n"; |
|
96
|
0
|
|
|
|
|
|
push @table, "\n\n"; |
|
97
|
|
|
|
|
|
|
|
|
98
|
0
|
|
|
|
|
|
push @table, "\n"; |
|
99
|
0
|
|
|
|
|
|
push @table, "\n";
|
100
|
0
|
0
|
|
|
|
|
push @table, qq().HTML::Entities::encode_entities($params{caption}).qq(\n) if defined $params{caption}; |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
# then the data |
|
103
|
0
|
|
|
|
|
|
my $i = -1; |
|
104
|
0
|
|
|
|
|
|
foreach my $row ( @{ $rows }[0..$#$rows] ) { |
|
|
0
|
|
|
|
|
|
|
|
105
|
0
|
|
|
|
|
|
$i++; |
|
106
|
0
|
|
|
|
|
|
my $in_header; |
|
107
|
0
|
0
|
|
|
|
|
if ($params{header_row}) { |
|
108
|
0
|
0
|
|
|
|
|
if ($i == 0) { push @table, "\n"; $in_header++ }
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
109
|
0
|
0
|
|
|
|
|
if ($i == 1) { push @table, " | | \n" }
|
|
0
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
} else { |
|
111
|
0
|
0
|
|
|
|
|
if ($i == 1) { push @table, " | \n" }
|
|
0
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
} |
|
113
|
|
|
|
|
|
|
push @table, join( |
|
114
|
|
|
|
|
|
|
"", |
|
115
|
|
|
|
|
|
|
" | ",
|
116
|
0
|
|
|
|
|
|
(map {( |
|
117
|
0
|
0
|
0
|
|
|
|
$in_header ? " | " : " | ", |
|
|
|
0
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
_encode($row->[$_] // ''), |
|
119
|
|
|
|
|
|
|
$in_header ? "" : " | ",
|
120
|
|
|
|
|
|
|
)} 0..$max_index), |
|
121
|
|
|
|
|
|
|
" | \n",
|
122
|
|
|
|
|
|
|
); |
|
123
|
0
|
0
|
0
|
|
|
|
if ($i == 0 && $params{header_row}) { |
|
124
|
0
|
|
|
|
|
|
push @table, "\n"; |
|
125
|
|
|
|
|
|
|
} |
|
126
|
|
|
|
|
|
|
} |
|
127
|
|
|
|
|
|
|
|
|
128
|
0
|
|
|
|
|
|
push @table, " | \n";
|
129
|
0
|
|
|
|
|
|
push @table, " | \n"; |
|
130
|
0
|
|
|
|
|
|
push @table, "\n\n"; |
|
131
|
|
|
|
|
|
|
|
|
132
|
0
|
|
|
|
|
|
push @table, "\n"; |
|
133
|
|
|
|
|
|
|
|
|
134
|
0
|
|
|
|
|
|
return join("", grep {$_} @table); |
|
|
0
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
} |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
# FROM_MODULE: PERLANCAR::List::Util::PP |
|
138
|
|
|
|
|
|
|
# BEGIN_BLOCK: max |
|
139
|
|
|
|
|
|
|
sub max { |
|
140
|
0
|
0
|
|
0
|
0
|
|
return undef unless @_; ## no critic: Subroutines::ProhibitExplicitReturnUndef |
|
141
|
0
|
|
|
|
|
|
my $res = $_[0]; |
|
142
|
0
|
|
|
|
|
|
my $i = 0; |
|
143
|
0
|
0
|
|
|
|
|
while (++$i < @_) { $res = $_[$i] if $_[$i] > $res } |
|
|
0
|
|
|
|
|
|
|
|
144
|
0
|
|
|
|
|
|
$res; |
|
145
|
|
|
|
|
|
|
} |
|
146
|
|
|
|
|
|
|
# END_BLOCK: max |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
# return highest top-index from all rows in case they're different lengths |
|
149
|
|
|
|
|
|
|
sub _max_array_index { |
|
150
|
0
|
|
|
0
|
|
|
my $rows = shift; |
|
151
|
0
|
|
|
|
|
|
return max( map { $#$_ } @$rows ); |
|
|
0
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
} |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
1; |
|
155
|
|
|
|
|
|
|
# ABSTRACT: Generate HTML table with jQuery and DataTables plugin |
|
156
|
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
__END__ |