Skip to content

Instantly share code, notes, and snippets.

@tokuhirom
Created December 29, 2008 14:59
Show Gist options
  • Save tokuhirom/41283 to your computer and use it in GitHub Desktop.
Save tokuhirom/41283 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use IO::File;
use Perl6::Say;
use Text::MicroTemplate qw/render_mt/;
use DateTime;
use Path::Class;
use Getopt::Long;
binmode STDOUT, ':utf8';
&main;exit;
sub main {
my $schedule_limit = 7; # schedule を何日ぶん表示するか
my $todo_limit = 20; # TODO を何件表示するか
GetOptions(
'todo-limit=i' => \$todo_limit,
'schedule-limit=i' => \$schedule_limit,
);
my @dirs = @ARGV;
my $rows = _aggregate(@dirs);
my $schedules = _find_schedules($rows, $schedule_limit);
my $todoes = _find_todoes($rows, $todo_limit);
print _render($schedules, $todoes);
}
sub _aggregate {
my @dirs = @_;
my @rows;
for my $dir (@dirs) {
die "$dir is not a directory" unless -d $dir;
dir($dir)->recurse(callback => sub {
my $file = shift;
return unless -f $file;
my $fh = IO::File->new($file, 'r');
$fh->binmode(':utf8');
while (my $line = <$fh>) {
if ($line =~ /\[(\d{4})-(\d\d)-(\d\d)\](.)\s*(.+)/) {
my ($y, $m, $d, $type, $body) = ($1, $2, $3, $4, $5);
push @rows => {
date => sprintf( '%04d-%02d-%02d', $y, $m, $d ),
y => $y,
m => $m,
d => $d,
type => $type,
body => $body,
};
}
}
$fh->close;
});
}
return \@rows;
}
sub _find_schedules {
my ($rows, $schedule_limit) = @_;
my $date_re = _date_re($schedule_limit);
my @schedules =
sort { $a->{date} cmp $b->{date} }
grep { $_->{date} =~ $date_re }
grep { $_->{type} =~ /[!\@]/ }
@$rows;
return \@schedules;
}
sub _find_todoes {
my ($rows, $todo_limit) = @_;
my @todoes = grep { $_->{type} =~ /^[!\+]$/ } @$rows;
@todoes = sort { $a->{date} cmp $b->{date} } @todoes;
@todoes = @todoes[0..$todo_limit];
return \@todoes;
}
sub _date_re {
my $limit = shift;
my @set;
my $dt = DateTime->today();
for (0..$limit) {
push @set, $dt->ymd;
$dt->add(days => 1); # DT は破壊的
}
my $src = join '|', @set;
qr{$src};
}
sub _render {
my ($schedules, $todoes) = @_;
my $tmpl = join '', <DATA>;
render_mt($tmpl, $schedules, $todoes)->as_string;
}
sub _type_class {
my $row = shift;
+{
'@' => 'type_schedule',
'+' => 'type_todo',
'!' => 'type_deadline',
}->{$row->{type}}
}
=head1 SYNOPSIS
$ howmtop2html.pl
--todo-limit=30 # 何件TODO表示するか
--schedule-limit=7 # 何日ぶんスケジュール表示するか
=head1 DESCRIPTION
howm の予定やらをケータイでみやすいようにフォーマットしちゃいます。
howm そのものよりも機能をそぎおとして軽量な実装です(「このスクリプトの実装は手抜きですよ」という意味の大人的表現。)
=head1 COPYRIGHT
This program is free software; you can redistribute
it and/or modify it under the same terms as Perl itself.
The full text of the license can be found in the
LICENSE file included with this module.
=cut
__END__
? my ($schedules, $todoes) = @_;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Cache-Control" content="max-age=0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>gp.ath.cx</title>
<style type="text/css">
body { background: black; color: white; font-family: Verdana, sans-seriff; font-size: 11pt; }
#page { background: #ffffff; margin: 4px; border: 2px solid #c0c0c0; padding: 1px; color: black; }
#header { background: #4b6983; border: 2px solid #7590ae; text-align: center; padding: 1px; color: black; }
#header h1 { color: #ffffff; }
#body { padding: 1px; }
.ttl { color: green; text-align: right; }
.content { font-size: x-small; }
span.type_deadline { color: red }
span.type_schedule { color: #3c33ff }
span.type_todo { color: #0ff522 }
.footer { font-size: xx-small; text-align: right; }
</style>
</head>
<body>
<div id="page">
<div id="title">howm.html</div>
<div class="ttl">schedule(@!)</div>
<div class="content">
? for my $schedule (@$schedules) {
<span class="date"><?= $schedule->{date} ?></span><span class="<?= _type_class($schedule) ?>"><?= $schedule->{type} ?></span><span class="body"><?= $schedule->{body} ?></span><br />
? }
</div>
<div class="ttl">todo(!+)</div>
<div class="content">
? for my $todo (@$todoes) {
<span class="date"><?= $todo->{date} ?></span><span class="<?= _type_class($todo) ?>"><?= $todo->{type} ?></span><span class="body"><?= $todo->{body} ?></span><br />
? }
</div>
<hr />
<div class="footer">
powered by hwomtop2html.pl by tokuhirom
</div>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment