The Perl and Raku Conference 2025: Greenville, South Carolina - June 27-29 Learn more

#!perl
use 5.010001;
use strict;
use Getopt::Long qw(:config gnu_getopt no_ignore_case);
our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
our $DATE = '2023-06-22'; # DATE
our $DIST = 'App-calx'; # DIST
our $VERSION = '0.009'; # VERSION
my %args = (
months => 1,
caldates_modules => [],
);
my $dates = [];
GetOptions(
'h' => sub { $args{highlight_today} = 0 },
'1' => sub { $args{months} = 1 },
'3' => sub { $args{months} = 3 },
'y' => sub { $args{months} = 12 },
'c=s' => $args{caldates_modules},
'date=s' => $dates,
'a' => sub {
my $mods = Module::List::Tiny::list_modules(
"Calendar::Dates::", {list_modules=>1, recurse=>1});
my @res = sort keys %$mods;
for (@res) { s/\ACalendar::Dates::// }
$args{caldates_modules} = \@res;
},
);
my $dt = DateTime->now;
my $re = qr/\A((\d{4})-(\d{2})-(\d{2}))(?:\t(.+))?\z/;
if (!(-t STDIN)) { ## no critic: InputOutput::ProhibitInteractiveTest
my @dates;
while (my $line = <STDIN>) {
chomp $line;
$line =~ $re or die "Invalid date syntax '$line'\n";
push @dates, {
date => $1,
day => $4,
month => $3,
year => $2,
summary => $5,
};
}
$args{dates} = \@dates;
} elsif (@$dates) {
my @dates;
for my $date (@$dates) {
$date =~ $re or die "Invalid date syntax '$date'\n";
push @dates, {
date => $1,
day => $4,
month => $3,
year => $2,
summary => $5,
};
}
$args{dates} = \@dates;
} elsif (@ARGV == 1) {
$args{year} = $ARGV[0];
$args{months} = 12;
} elsif (@ARGV == 2) {
$args{month} = $ARGV[0];
$args{year} = $ARGV[1];
} else {
$args{month} = $dt->month;
$args{year} = $dt->year;
}
if ($args{months} == 3) {
$dt = DateTime->new(year=>$args{year}, month=>$args{month}//1, day=>1);
$dt->subtract(months=>1);
$args{month} = $dt->month;
$args{year} = $dt->year;
}
my $res = App::calx::gen_calendar(%args);
die $res->[1] unless $res->[0] == 200;
say $res->[2];
1;
# ABSTRACT: Display calendar, with highlighted dates
# PODNAME: calx
__END__
=pod
=encoding UTF-8
=head1 NAME
calx - Display calendar, with highlighted dates
=head1 VERSION
This document describes version 0.009 of calx (from Perl distribution App-calx), released on 2023-06-22.
=head1 SYNOPSIS
# show calendar for the current month, with dates from Calendar::Dates::ID::Holiday
% calx -c ID::Holiday
# show calendar for the current month, with dates from Calendar::Dates::ID::Holiday and Calendar::Dates::SG::Holiday
% calx -c ID::Holiday -c SD::Holiday
# show calendar for the current month, with dates from all installed Calendar::Dates::* modules
% calx -a
# show calendar for the whole year
% calx 2019 -c ID::Holiday
# show calendar for a certain month and year
% calx 2 2019 -c ID::Holiday
# echo -e "2023-05-30\n2023-05-31\n2023-06-01\n" | calx
=head1 DESCRIPTION
This command provides a variant of B<cal> utility for displaying ASCII calendar
on the command-line. It focuses on highlighting certain dates. It currently
always starts the week at Monday and can get the list of dates from command-line
option (`--date`) or stdin or one or more L<Calendar::Dates>::* modules.
=head1 OPTIONS
% calx [opts] [[month] year]
Most options follow B<cal>. Not all options from B<cal> are
supported/recognized. Some options are specific to B<calx>.
=head2 -1
Show a single month of calendar (the default).
=head2 -3
Show three months of calendar (previous, current, next).
=head2 -h
Turn off highlighting of today.
=head2 -y
Show one year (12 months) of calendar (the default if only year is specified).
=head2 -c MODULE+
Get dates from a L<Calendar::Dates> module (value is name of module without the
"Calendar::Dates::" prefix). Can be specified multiple times.
=head2 -a
Get dates from all installed C<Calendar::Dates::*> modules.
=head2 --date DATE+
Highlight one or more dates. You can also supply the dates from stdin. The dates
must be in ISO8601 C<YYYY-MM-DD> format.
=head1 HOMEPAGE
Please visit the project's homepage at L<https://metacpan.org/release/App-calx>.
=head1 SOURCE
Source repository is at L<https://github.com/perlancar/perl-App-calx>.
=head1 SEE ALSO
B<cal> Unix utility
L<Calendar::Dates>
B<cal> Unix utility.
Other B<cal> variants: L<cal-idn> (from L<App::cal::idn>).
=head1 AUTHOR
perlancar <perlancar@cpan.org>
=head1 CONTRIBUTING
To contribute, you can send patches by email/via RT, or send pull requests on
GitHub.
Most of the time, you don't need to build the distribution yourself. You can
simply modify the code, then test via:
% prove -l
If you want to build the distribution (e.g. to try to install it locally on your
system), you can install L<Dist::Zilla>,
L<Dist::Zilla::PluginBundle::Author::PERLANCAR>,
L<Pod::Weaver::PluginBundle::Author::PERLANCAR>, and sometimes one or two other
Dist::Zilla- and/or Pod::Weaver plugins. Any additional steps required beyond
that are considered a bug and can be reported to me.
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2023, 2019 by perlancar <perlancar@cpan.org>.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=App-calx>
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=cut