Since this is a little bit er, stalled, I'll post here the stuff Manoj
mailed me, and my response to it. --[[Joey]]
-[[tag patch]]
-
-<pre>
-#! /usr/bin/perl
-# -*- Mode: Cperl -*-
-# calendar.pm ---
-# Author : Manoj Srivastava ( srivasta@glaurung.internal.golden-gryphon.com )
-# Created On : Fri Dec 8 16:05:48 2006
-# Created On Node : glaurung.internal.golden-gryphon.com
-# Last Modified By : Manoj Srivastava
-# Last Modified On : Sun Dec 10 01:53:22 2006
-# Last Machine Used: glaurung.internal.golden-gryphon.com
-# Update Count : 139
-# Status : Unknown, Use with caution!
-# HISTORY :
-# Description :
-#
-# arch-tag: 2aa737c7-3d62-4918-aaeb-fd85b4b1384c
-#
-# Copyright (c) 2006 Manoj Srivastava <srivasta@debian.org>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-require 5.002;
-package IkiWiki::Plugin::calendar;
-
-use warnings;
-use strict;
-use IkiWiki '1.00';
-use Time::Local;
-
-our $VERSION = "0.1";
-my $file = __FILE__;
-
-my %calpages;
-my %cache;
-my %linkcache;
-
-my $index=1;
-my @now=localtime();
-
-=head1 NAME
-
-calendar - Add links for the current month's, current year's, and older archived postings
-
-=cut
-
-=head1 SYNOPSIS
-
-To invoke the calendar, just use the preprocessor directive (options
-and variations are detailed below):
-
- [[calendar ]]
-
-or
-
- [[calendar type="month" pages="blog/* and !*/Discussion"]]
-
-or
-
- [[calendar type="year" year="2005" pages="blog/* and !*/Discussion"]]
-
-=cut
-
-
-=head1 DESCRIPTION
-
-This plugin is inspired by the calendar plugin for Blosxom, but
-derives no code from it. This plugin is essentially a fancy front end
-to archives of previous pages, usually used for blogs. It can produce
-a calendar for a given month, or a list of months for a given year.
-
-The year and month entities in the out put have links to archive index
-pages, which are supposed to exist already. The idea is to create an
-archives hierarchy, rooted in the subdirectory specified in the
-site wide customization variable, I<archivebase>. I<archivebase>
-defaults to C<archives>. Links are created to pages
-C<$archivebase/$year> and C<$archivebase/$year/$month>. If one creates
-annual and monthly indices, for example, by using something like this
-sample from my I<archives/2006/01.mdwn> (warning: line split for
-readability):
-
- \[[meta title="Archives for 2006/01"]]
- \[[inline rootpage="blog" atom="no" rss="no" show="0"
- pages="blog/* and !*/Discussion and creation_year(2006)
- and creation_month(01)"
- ]]
-
-=cut
-
-=head1 OPTIONS
-
-=over
-
-=item B<type>
-
-Used to specify the type of calendar wanted. Can be one of C<month> or
-C<year>. The default is a month view calendar.
-
-=item B<pages>
-
-Specifies the C<pagespec> used to get pages to match for
-linking. Usually this should be something like C<blog/* and !*/Discussion>.
-Defaults to C<*>.
-
-=item B<year>
-
-The year for which the calendar is requested. Defaults to the current year.
-
-=item B<month>
-
-The numeric month for which the calendar is requested, in the range
-1..12. Used only for the month view calendar, and defaults to the
-current month.
-
-=item B<week_start_day>
-
-A number, in the range 0..6, which represents the day of the week that
-the month calendar starts with. 0 is Sunday, 1 is Monday, and so
-on. Defaults to 0, which is Sunday.
-
-=item B<months_per_row>
-
-In the annual calendar, number of months to place in each row. Defaults to 3.
-
-=back
-
-=cut
-
-=head1 Classes for CSS control
-
-The output is liberally sprinkled with classes, for fine grained CSS
-customization.
-
-=over
-
-=item C<month-calendar>
-
-The month calendar as a whole
-
-=item C<month-calendar-head>
+> > I'm sending in an updated package, and have removed the older version you had here.--ManojSrivastava
-The head of the month calendar (ie,"March"), localized to the environment.
-=item C<month-calendar-day-head>
-
-A column head in the month calendar (ie, a day-of-week abbreviation),
-localized.
-
-=item C<month-calendar-day-noday>, C<month-calendar-day-link>,
- C<month-calendar-day-nolink>, C<month-calendar-day-future>,
- C<month-calendar-day-this-day>
-
-The day squares on the month calendar, for days that don't exist
-(before or after the month itself), that don't have stories, that do
-have stories, that are in the future, or are that currently selected,
-respectively (today).
-
-=item Day-of-week-name
-
-Each day square is also given a class matching its day of week, this
-can be used to high light weekends. This is also localized.
-
-=item C<year-calendar>
-
-The year calendar as a whole
-
-=item C<year-calendar-head>
-
-The head of the year calendar (ie, "2006")
-
-=item C<year-calendar-subhead>
-
-For example, "Months"
-
-=item C<year-calendar-month-link>, C<year-calendar-month-nolink>,
- C<year-calendar-month-future>, C<year-calendar-this-month>
-
-The month squares on the year calendar, for months with stories,
-without, in the future, and currently selected, respectively.
-
-=back
-
-=cut
-
-
-sub import {
- hook(type => "preprocess", id => "calendar", call => \&preprocess);
- hook(type => "format", id => "calendar", call => \&format);
-}
-
-sub preprocess (@) {
- my %params=@_;
- $params{pages} = "*" unless defined $params{pages};
- $params{type} = "month" unless defined $params{type};
- $params{year} = 1900 + $now[5] unless defined $params{year};
- $params{month} = sprintf("%02d", $params{month}) if defined $params{month};
- $params{month} = 1 + $now[4] unless defined $params{month};
- $params{week_start_day} = 0 unless defined $params{week_start_day};
- $params{months_per_row} = 3 unless defined $params{months_per_row};
-
- # Store parameters (could be multiple calls per page)
- $calpages{$params{destpage}}{$index} = \%params;
-
- return "\n<div class=\"calendar\">" . $index++ . "</div><!-- calendar -->\n";
-}
-
-sub is_leap_year (@) {
- my %params=@_;
- return ($params{year} % 4 == 0 && (($params{year} % 100 != 0) || $params{year} % 400 ==0)) ;
-}
-
-
-sub month_days {
- my %params=@_;
- my $days_in_month = (31,28,31,30,31,30,31,31,30,31,30,31)[$params{month}-1];
- if ($params{month} == 2 && is_leap_year(%params)) {
- $days_in_month++;
- }
- return $days_in_month;
-}
-
-
-sub format_month (@) {
- my %params=@_;
- my $pagespec = $params{pages};
- my $year = $params{year};
- my $month = $params{month};
-
- my $calendar="\n";
-
- # When did this month start?
- my @monthstart = localtime(timelocal(0,0,0,1,$month-1,$year-1900));
-
- my $future_dom = 0;
- my $today = 0;
- $future_dom = $now[3]+1 if ($year == $now[5]+1900 && $month == $now[4]+1);
- $today = $now[3] if ($year == $now[5]+1900 && $month == $now[4]+1);
-
- # Calculate month names for next month, and previous months
- my $pmonth = $month - 1;
- my $nmonth = $month + 1;
- my $pyear = $year;
- my $nyear = $year;
-
- # Adjust for January and December
- if ($month == 1) { $pmonth = 12; $pyear--; }
- if ($month == 12) { $nmonth = 1; $nyear++; }
-
- # Find out month names for this, next, and previous months
- my $monthname=POSIX::strftime("%B", @monthstart);
- my $pmonthname=
- POSIX::strftime("%B", localtime(timelocal(0,0,0,1,$pmonth-1,$pyear-1900)));
- my $nmonthname=
- POSIX::strftime("%B", localtime(timelocal(0,0,0,1,$nmonth-1,$nyear-1900)));
-
- # Calculate URL's for monthly archives, and article counts
- my $archivebase = 'archives';
- $archivebase = $config{archivebase} if defined $config{archivebase};
-
- my ($url, $purl, $nurl)=("$monthname",'','');
- my ($count, $pcount, $ncount) = (0,0,0);
-
- if (exists $cache{$pagespec}{"$year/$month"}) {
- $url = htmllink($params{page}, $params{destpage},
- "$archivebase/$year/" . sprintf("%02d", $month),
- 0,0," $monthname ");
- }
-
- if (exists $cache{$pagespec}{"$pyear/$pmonth"}) {
- $purl = htmllink($params{page}, $params{destpage},
- "$archivebase/$pyear/" . sprintf("%02d", $pmonth),
- 0,0," $pmonthname ");
- }
- if (exists $cache{$pagespec}{"$nyear/$nmonth"}) {
- $nurl = htmllink($params{page}, $params{destpage},
- "$archivebase/$nyear/" . sprintf("%02d", $nmonth),
- 0,0," $nmonthname ");
- }
-
- # Start producing the month calendar
- $calendar=<<EOF;
-<table class="month-calendar">
- <caption class="month-calendar-head">
- $purl
- $url
- $nurl
- </caption>
- <tr>
-EOF
- # Suppose we want to start the week with day $week_start_day
- # If $monthstart[6] == 1
- my $week_start_day = $params{week_start_day};
-
- my $start_day = 1 + (7 - $monthstart[6] + $week_start_day) % 7;
- my %downame;
- my %dowabbr;
- for my $dow ($week_start_day..$week_start_day+6) {
- my @day=localtime(timelocal(0,0,0,$start_day++,$month-1,$year-1900));
- my $downame = POSIX::strftime("%A", @day);
- my $dowabbr = POSIX::strftime("%a", @day);
- $downame{$dow % 7}=$downame;
- $dowabbr{$dow % 7}=$dowabbr;
- $calendar.=
- qq{ <th class="month-calendar-day-head $downame">$dowabbr</th>\n};
- }
-
- $calendar.=<<EOF;
- </tr>
-EOF
-
- my $wday;
- # we start with a week_start_day, and skip until we get to the first
- for ($wday=$week_start_day; $wday != $monthstart[6]; $wday++, $wday %= 7) {
- $calendar.=qq{ <tr>\n} if $wday == $week_start_day;
- $calendar.=
- qq{ <td class="month-calendar-day-noday $downame{$wday}"> </td>\n};
- }
-
- # At this point, either the first is a week_start_day, in which case nothing
- # has been printed, or else we are in the middle of a row.
- for (my $day = 1; $day <= month_days(year => $year, month => $month);
- $day++, $wday++, $wday %= 7) {
- # At tihs point, on a week_start_day, we close out a row, and start a new
- # one -- unless it is week_start_day on the first, where we do not close a
- # row -- since none was started.
- if ($wday == $week_start_day) {
- $calendar.=qq{ </tr>\n} unless $day == 1;
- $calendar.=qq{ <tr>\n};
- }
- my $tag;
- my $mtag = sprintf("%02d", $month);
- if (defined $cache{$pagespec}{"$year/$mtag/$day"}) {
- if ($day == $today) { $tag='month-calendar-day-this-day'; }
- else { $tag='month-calendar-day-link'; }
- $calendar.=qq{ <td class="$tag $downame{$wday}">};
- $calendar.=
- htmllink($params{page}, $params{destpage},
- pagename($linkcache{"$year/$mtag/$day"}),
- 0,0,"$day");
- $calendar.=qq{</td>\n};
- }
- else {
- if ($day == $today) { $tag='month-calendar-day-this-day'; }
- elsif ($day == $future_dom) { $tag='month-calendar-day-future'; }
- else { $tag='month-calendar-day-nolink'; }
- $calendar.=qq{ <td class="$tag $downame{$wday}">$day</td>\n};
- }
- }
- # finish off the week
- for (; $wday != $week_start_day; $wday++, $wday %= 7) {
- $calendar.=qq{ <td class="month-calendar-day-noday $downame{$wday}"> </td>\n};
- }
- $calendar.=<<EOF;
- </tr>
-</table>
-EOF
-
- return $calendar;
-}
-
-sub format_year (@) {
- my %params=@_;
- my $pagespec = $params{pages};
- my $year = $params{year};
- my $month = $params{month};
- my $calendar="\n";
- my $pyear = $year - 1;
- my $nyear = $year + 1;
- my $future_month = 0;
- $future_month = $now[4]+1 if ($year == $now[5]+1900);
-
- # calculate URL's for previous and next years
- my $archivebase = 'archives';
- $archivebase = $config{archivebase} if defined $config{archivebase};
- my ($url, $purl, $nurl)=("$year",'','');
- if (exists $cache{$pagespec}{"$year"}) {
- $url = htmllink($params{page}, $params{destpage},
- "$archivebase/$year",
- 0,0,"$year");
- }
-
- if (exists $cache{$pagespec}{"$pyear"}) {
- $purl = htmllink($params{page}, $params{destpage},
- "$archivebase/$pyear",
- 0,0,"\←");
- }
- if (exists $cache{$pagespec}{"$nyear"}) {
- $nurl = htmllink($params{page}, $params{destpage},
- "$archivebase/$nyear",
- 0,0,"\→");
- }
- # Start producing the year calendar
- $calendar=<<EOF;
-<table class="year-calendar">
- <caption class="year-calendar-head">
- $purl
- $url
- $nurl
- </caption>
- <tr>
- <th class="year-calendar-subhead" colspan="$params{months_per_row}">Months</th>
- </tr>
-EOF
-
- for ($month = 1; $month <= 12; $month++) {
- my @day=localtime(timelocal(0,0,0,15,$month-1,$year-1900));
- my $murl;
- my $monthname = POSIX::strftime("%B", @day);
- my $monthabbr = POSIX::strftime("%b", @day);
- $calendar.=qq{ <tr>\n} if ($month % $params{months_per_row} == 1);
- my $tag;
- my $mtag=sprintf("%02d", $month);
- if ($month == $params{month}) {
- if ($cache{$pagespec}{"$year/$mtag"}) {$tag = 'this_month_link'}
- else {$tag = 'this_month_nolink'}
- }
- elsif ($cache{$pagespec}{"$year/$mtag"}) {$tag = 'month_link'}
- elsif ($future_month && $month >=$future_month){$tag = 'month_future'}
- else {$tag = 'month_nolink'}
- if ($cache{$pagespec}{"$year/$mtag"}) {
- $murl = htmllink($params{page}, $params{destpage},
- "$archivebase/$year/$mtag",
- 0,0,"$monthabbr");
- $calendar.=qq{ <td class="$tag">};
- $calendar.=$murl;
- $calendar.=qq{</td>\n};
- }
- else {
- $calendar.=qq{ <td class="$tag">$monthabbr</td>\n};
- }
- $calendar.=qq{ </tr>\n} if ($month % $params{months_per_row} == 0);
- }
- $calendar.=<<EOF;
-</table>
-EOF
-
- return $calendar;
-}
-
-
-sub format (@) {
- my %params=@_;
- my $content=$params{content};
- return $content unless exists $calpages{$params{page}};
-
- # Restore parameters for each invocation
- foreach my $index (keys %{$calpages{$params{page}}}) {
- my $calendar="\n";
- my %saved = %{$calpages{$params{page}}{$index}};
- my $pagespec=$saved{pages};
-
- if (! defined $cache{$pagespec}) {
- for my $page (sort keys %pagesources) {
- next unless pagespec_match($page,$pagespec);
- my $mtime;
- my $src = $pagesources{$page};
- if (! exists $IkiWiki::pagectime{$page}) {
- $mtime=(stat(srcfile($src)))[9];
- }
- else {
- $mtime=$IkiWiki::pagectime{$page}
- }
- my @date = localtime($mtime);
- my $mday = $date[3];
- my $month = $date[4] + 1;
- my $year = $date[5] + 1900;
- my $mtag = sprintf("%02d", $month);
- $linkcache{"$year/$mtag/$mday"} = "$src";
- $cache{$pagespec}{"$year"}++;
- $cache{$pagespec}{"$year/$mtag"}++;
- $cache{$pagespec}{"$year/$mtag/$mday"}++;
- }
- }
- # So, we have cached data for the current pagespec at this point
- if ($saved{type} =~ /month/i) {
- $calendar=format_month(%saved);
- }
- elsif ($saved{type} =~ /year/i) {
- $calendar=format_year(%saved);
- }
- $content =~ s/(<div class=\"calendar\">\s*.?\s*$index\b)/<div class=\"calendar\">$calendar/ms;
- }
- return $content;
-}
-
-
-
-=head1 CAVEATS
-
-In the month calendar, for days in which there is more than one
-posting, the link created randomly selects one of them. Since there is
-no easy way in B<IkiWiki> to automatically generate index pages, and
-pregenerating daily index pages seems too much of an overhead, we have
-to live with this. All postings can still be viewed in the monthly or
-annual indices, of course. This can be an issue for very prolific
-scriveners.
-
-=cut
-
-=head1 BUGS
-
-None Known so far.
-
-=head1 BUGS
-
-Since B<IkiWiki> eval's the configuration file, the values have to all
-on a single physical line. This is the reason we need to use strings
-and eval, instead of just passing in real anonymous sub references,
-since the eval pass converts the coderef into a string of the form
-"(CODE 12de345657)" which can't be dereferenced.
-
-=cut
-
-=head1 AUTHOR
-
-Manoj Srivastava <srivasta@debian.org>
-
-=head1 COPYRIGHT AND LICENSE
-
-This script is a part of the Devotee package, and is
-
-Copyright (c) 2002 Manoj Srivastava <srivasta@debian.org>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-=cut
-
-1;
-
-__END__
-</pre>
+[[tag patch]]
-------
+----
-I've been looking over the calendar plugin. Some items:
+'ve been looking over the calendar plugin. Some items:
* Why did you need to use a two-stage generation with a format hook?
That approach should only be needed if adding something to a page that
----
-
And that's all I've heard so far. Hoping I didn't miss another patch?
--[[Joey]]
+
+>No, you did not. But I am back to hacking on this, and I think I have discovered a major problem with my approach. One of the problems with the current plugin is that the goal of a calendar is to create a calendar, either a month >or year based on, that provides links to blogs for all the days in (for the month calendar), and all the months (in a year calendar) in which there have been blog postings. For the monthly calendar, it needs to know the previous >and next months where there is a posting, and for the year calendar, it needs to know which of the previous (next) years had entries.
+
+>Now, this means that it needs to know about at _all_ pages that meet the pagespec, and stash that information, before it begins generating the calandar in question, in order to calculate how to create the symlinks. And, of >course, all pages that have calendars on them might need to change anytime a page that meets the pagespec is added; and again at midnight, when the current day changes.
+
+>> I think I have solved the ""Need to look at all pages that match the spec"" issue; but the nightly rebuild to handle the current day changing still remain. I use cron. It is now, however, richly documented :)
+
+
+--ManojSrivastava
+
+> Finally reviewed and applied this. [[done]]! --[[Joey]]