File Coverage

blib/lib/Comparer/date_in_text.pm
Criterion Covered Total %
statement 14 66 21.2
branch 0 30 0.0
condition 0 15 0.0
subroutine 5 12 41.6
pod 0 2 0.0
total 19 125 15.2


line stmt bran cond sub pod time code
1             package Comparer::date_in_text;
2              
3 1     1   369969 use 5.010001;
  1         5  
4 1     1   7 use strict;
  1         2  
  1         34  
5 1     1   7 use warnings;
  1         2  
  1         71  
6              
7 1     1   1604 use DateTime;
  1         725082  
  1         428  
8              
9             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
10             our $DATE = '2024-03-06'; # DATE
11             our $DIST = 'Comparer-date_in_text'; # DIST
12             our $VERSION = '0.001'; # VERSION
13              
14             our $DATE_EXTRACT_MODULE = $ENV{PERL_DATE_EXTRACT_MODULE} // "Date::Extract";
15              
16             sub meta {
17             return {
18 0     0 0   v => 1,
19             args => {
20             reverse => {schema=>'bool*'},
21             ci => {schema=>'bool*'},
22             },
23             };
24             }
25              
26             my $re_is_num = qr/\A
27             [+-]?
28             (?:\d+|\d*(?:\.\d*)?)
29             (?:[Ee][+-]?\d+)?
30             \z/x;
31              
32             sub gen_comparer {
33 0     0 0   my %args = @_;
34              
35 0           my $reverse = $args{reverse};
36 0           my $ci = $args{ci};
37              
38 0           my ($parser, $code_parse);
39 0 0         unless (defined $parser) {
40 0           my $module = $DATE_EXTRACT_MODULE;
41 0 0         $module = "Date::Extract::$module" unless $module =~ /::/;
42 0 0         if ($module eq 'Date::Extract') {
    0          
    0          
    0          
43 0           require Date::Extract;
44 0           $parser = Date::Extract->new();
45 0     0     $code_parse = sub { $parser->extract($_[0]) };
  0            
46             } elsif ($module eq 'Date::Extract::ID') {
47 0           require Date::Extract::ID;
48 0           $parser = Date::Extract::ID->new();
49 0     0     $code_parse = sub { $parser->extract($_[0]) };
  0            
50             } elsif ($module eq 'DateTime::Format::Alami::EN') {
51 0           require DateTime::Format::Alami::EN;
52 0           $parser = DateTime::Format::Alami::EN->new();
53 0     0     $code_parse = sub { my $h; eval { $h = $parser->parse_datetime($_[0]) }; $h }; ## no critic: BuiltinFunctions::ProhibitStringyEval
  0            
  0            
  0            
  0            
54             } elsif ($module eq 'DateTime::Format::Alami::ID') {
55 0           require DateTime::Format::Alami::ID;
56 0           $parser = DateTime::Format::Alami::ID->new();
57 0     0     $code_parse = sub { my $h; eval { $h = $parser->parse_datetime($_[0]) }; $h }; ## no critic: BuiltinFunctions::ProhibitStringyEval
  0            
  0            
  0            
  0            
58             } else {
59 0           die "Invalid date extract module '$module'";
60             }
61 0 0         eval "use $module"; die if $@; ## no critic: BuiltinFunctions::ProhibitStringyEval
  0            
62             }
63              
64             sub {
65 1     1   9 no strict 'refs'; ## no critic: TestingAndDebugging::ProhibitNoStrict
  1         2  
  1         271  
66              
67 0     0     my $cmp;
68              
69             # XXX cache
70              
71 0           my $dt_a = $code_parse->($_[0]);
72 0 0 0       warn "Found date $dt_a in $_[0]\n" if $ENV{DEBUG} && $dt_a;
73 0           my $dt_b = $code_parse->($_[1]);
74 0 0 0       warn "Found date $dt_b in $_[1]\n" if $ENV{DEBUG} && $dt_b;
75              
76             {
77 0 0 0       if ($dt_a && $dt_b) {
  0 0 0        
    0 0        
78 0           $cmp = DateTime->compare($dt_a, $dt_b);
79 0 0         last if $cmp;
80             } elsif ($dt_a && !$dt_b) {
81 0           $cmp = -1;
82 0           last;
83             } elsif (!$dt_a && $dt_b) {
84 0           $cmp = 1;
85 0           last;
86             }
87              
88 0 0         if ($ci) {
89 0           $cmp = lc($a) cmp lc($b);
90             } else {
91 0           $cmp = $a cmp $b;
92             }
93             }
94              
95 0 0         $reverse ? -1*$cmp : $cmp;
96 0           };
97             }
98              
99             1;
100             # ABSTRACT: Compare date found in text (or text asciibetically, if no date is found)
101              
102             __END__
103              
104             =pod
105              
106             =encoding UTF-8
107              
108             =head1 NAME
109              
110             Comparer::date_in_text - Compare date found in text (or text asciibetically, if no date is found)
111              
112             =head1 VERSION
113              
114             This document describes version 0.001 of Comparer::date_in_text (from Perl distribution Comparer-date_in_text), released on 2024-03-06.
115              
116             =head1 DESCRIPTION
117              
118             The generated comparer routine will compare text by date found in it (extracted
119             using L<Date::Extract>, but other module can be selected, see
120             L</PERL_DATE_EXTRACT_MODULE>) or (f no date is found in text) ascibetically.
121             Items that have a date will sort before items that do not.
122              
123             =for Pod::Coverage ^(gen_comparer|meta)$
124              
125             =head1 ENVIRONMENT
126              
127             =head2 DEBUG => bool
128              
129             If set to true, will print stuffs to stderr.
130              
131             =head2 PERL_DATE_EXTRACT_MODULE => str
132              
133             Can be set to L<Date::Extract>, L<Date::Extract::ID>, or
134             L<DateTime::Format::Alami::EN>, L<DateTime::Format::Alami::ID>.
135              
136             =head1 HOMEPAGE
137              
138             Please visit the project's homepage at L<https://metacpan.org/release/Comparer-date_in_text>.
139              
140             =head1 SOURCE
141              
142             Source repository is at L<https://github.com/perlancar/perl-Comparer-date_in_text>.
143              
144             =head1 SEE ALSO
145              
146             L<SortKey> version: L<SortKey::date_in_text>.
147              
148             Old incarnation: L<Sort::Sub::by_date_in_text>.
149              
150             =head1 AUTHOR
151              
152             perlancar <perlancar@cpan.org>
153              
154             =head1 CONTRIBUTING
155              
156              
157             To contribute, you can send patches by email/via RT, or send pull requests on
158             GitHub.
159              
160             Most of the time, you don't need to build the distribution yourself. You can
161             simply modify the code, then test via:
162              
163             % prove -l
164              
165             If you want to build the distribution (e.g. to try to install it locally on your
166             system), you can install L<Dist::Zilla>,
167             L<Dist::Zilla::PluginBundle::Author::PERLANCAR>,
168             L<Pod::Weaver::PluginBundle::Author::PERLANCAR>, and sometimes one or two other
169             Dist::Zilla- and/or Pod::Weaver plugins. Any additional steps required beyond
170             that are considered a bug and can be reported to me.
171              
172             =head1 COPYRIGHT AND LICENSE
173              
174             This software is copyright (c) 2024 by perlancar <perlancar@cpan.org>.
175              
176             This is free software; you can redistribute it and/or modify it under
177             the same terms as the Perl 5 programming language system itself.
178              
179             =head1 BUGS
180              
181             Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=Comparer-date_in_text>
182              
183             When submitting a bug or request, please include a test-file or a
184             patch to an existing test-file that illustrates the bug or desired
185             feature.
186              
187             =cut