diff options
Diffstat (limited to 'IkiWiki/Plugin')
-rw-r--r-- | IkiWiki/Plugin/aggregate.pm | 3 | ||||
-rw-r--r-- | IkiWiki/Plugin/calendar.pm | 3 | ||||
-rw-r--r-- | IkiWiki/Plugin/ddate.pm | 6 | ||||
-rw-r--r-- | IkiWiki/Plugin/edittemplate.pm | 3 | ||||
-rw-r--r-- | IkiWiki/Plugin/inline.pm | 2 | ||||
-rw-r--r-- | IkiWiki/Plugin/meta.pm | 125 | ||||
-rw-r--r-- | IkiWiki/Plugin/prettydate.pm | 5 | ||||
-rw-r--r-- | IkiWiki/Plugin/recentchanges.pm | 116 | ||||
-rw-r--r-- | IkiWiki/Plugin/version.pm | 3 |
9 files changed, 219 insertions, 47 deletions
diff --git a/IkiWiki/Plugin/aggregate.pm b/IkiWiki/Plugin/aggregate.pm index 71368e254..2a4d10411 100644 --- a/IkiWiki/Plugin/aggregate.pm +++ b/IkiWiki/Plugin/aggregate.pm @@ -66,7 +66,8 @@ sub needsbuild (@) { #{{{ loadstate(); # if not already loaded foreach my $feed (values %feeds) { - if (grep { $_ eq $pagesources{$feed->{sourcepage}} } @$needsbuild) { + if (exists $pagesources{$feed->{sourcepage}} && + grep { $_ eq $pagesources{$feed->{sourcepage}} } @$needsbuild) { # Mark all feeds originating on this page as removable; # preprocess will unmark those that still exist. remove_feeds($feed->{sourcepage}); diff --git a/IkiWiki/Plugin/calendar.pm b/IkiWiki/Plugin/calendar.pm index 4bb4c2c21..aed087eed 100644 --- a/IkiWiki/Plugin/calendar.pm +++ b/IkiWiki/Plugin/calendar.pm @@ -390,7 +390,8 @@ sub needsbuild (@) { #{{{ # the current day push @$needsbuild, $pagesources{$page}; } - if (grep { $_ eq $pagesources{$page} } @$needsbuild) { + if (exists $pagesources{$page} && + grep { $_ eq $pagesources{$page} } @$needsbuild) { # remove state, will be re-added if # the calendar is still there during the # rebuild diff --git a/IkiWiki/Plugin/ddate.pm b/IkiWiki/Plugin/ddate.pm index 6b67f4202..d081cb509 100644 --- a/IkiWiki/Plugin/ddate.pm +++ b/IkiWiki/Plugin/ddate.pm @@ -18,6 +18,10 @@ sub checkconfig () { #{{{ sub IkiWiki::displaytime ($;$) { #{{{ my $time=shift; + my $format=shift; + if (! defined $format) { + $format=$config{timeformat}; + } eval q{ use DateTime; use DateTime::Calendar::Discordian; @@ -27,7 +31,7 @@ sub IkiWiki::displaytime ($;$) { #{{{ } my $dt = DateTime->from_epoch(epoch => $time); my $dd = DateTime::Calendar::Discordian->from_object(object => $dt); - return $dd->strftime($IkiWiki::config{timeformat}); + return $dd->strftime($format); } #}}} 5 diff --git a/IkiWiki/Plugin/edittemplate.pm b/IkiWiki/Plugin/edittemplate.pm index aa72b0845..b7651ce02 100644 --- a/IkiWiki/Plugin/edittemplate.pm +++ b/IkiWiki/Plugin/edittemplate.pm @@ -21,7 +21,8 @@ sub needsbuild (@) { #{{{ foreach my $page (keys %pagestate) { if (exists $pagestate{$page}{edittemplate}) { - if (grep { $_ eq $pagesources{$page} } @$needsbuild) { + if (exists $pagesources{$page} && + grep { $_ eq $pagesources{$page} } @$needsbuild) { # remove state, it will be re-added # if the preprocessor directive is still # there during the rebuild diff --git a/IkiWiki/Plugin/inline.pm b/IkiWiki/Plugin/inline.pm index 59eabb606..796cf2cf6 100644 --- a/IkiWiki/Plugin/inline.pm +++ b/IkiWiki/Plugin/inline.pm @@ -231,6 +231,8 @@ sub preprocess_inline (@) { #{{{ $template->param(pageurl => urlto(bestlink($params{page}, $page), $params{destpage})); $template->param(title => pagetitle(basename($page))); $template->param(ctime => displaytime($pagectime{$page}, $params{timeformat})); + $template->param(first => 1) if $page eq $list[0]; + $template->param(last => 1) if $page eq $list[$#list]; if ($actions) { my $file = $pagesources{$page}; diff --git a/IkiWiki/Plugin/meta.pm b/IkiWiki/Plugin/meta.pm index d2c6e7f8b..621e87674 100644 --- a/IkiWiki/Plugin/meta.pm +++ b/IkiWiki/Plugin/meta.pm @@ -6,13 +6,7 @@ use warnings; use strict; use IkiWiki 2.00; -my %meta; -my %title; -my %permalink; -my %author; -my %authorurl; -my %license; -my %copyright; +my %metaheaders; sub import { #{{{ hook(type => "needsbuild", id => "meta", call => \&needsbuild); @@ -24,7 +18,8 @@ sub needsbuild (@) { #{{{ my $needsbuild=shift; foreach my $page (keys %pagestate) { if (exists $pagestate{$page}{meta}) { - if (grep { $_ eq $pagesources{$page} } @$needsbuild) { + if (exists $pagesources{$page} && + grep { $_ eq $pagesources{$page} } @$needsbuild) { # remove state, it will be re-added # if the preprocessor directive is still # there during the rebuild @@ -71,16 +66,16 @@ sub preprocess (@) { #{{{ # Metadata collection that needs to happen during the scan pass. if ($key eq 'title') { - $title{$page}=HTML::Entities::encode_numeric($value); + $pagestate{$page}{meta}{title}=HTML::Entities::encode_numeric($value); } elsif ($key eq 'license') { - push @{$meta{$page}}, '<link rel="license" href="#page_license" />'; - $license{$page}=$value; + push @{$metaheaders{$page}}, '<link rel="license" href="#page_license" />'; + $pagestate{$page}{meta}{license}=$value; return ""; } elsif ($key eq 'copyright') { - push @{$meta{$page}}, '<link rel="copyright" href="#page_copyright" />'; - $copyright{$page}=$value; + push @{$metaheaders{$page}}, '<link rel="copyright" href="#page_copyright" />'; + $pagestate{$page}{meta}{copyright}=$value; return ""; } elsif ($key eq 'link' && ! %params) { @@ -89,11 +84,11 @@ sub preprocess (@) { #{{{ return ""; } elsif ($key eq 'author') { - $author{$page}=$value; + $pagestate{$page}{meta}{author}=$value; # fallthorough } elsif ($key eq 'authorurl') { - $authorurl{$page}=$value; + $pagestate{$page}{meta}{authorurl}=$value; # fallthrough } @@ -111,8 +106,8 @@ sub preprocess (@) { #{{{ } } elsif ($key eq 'permalink') { - $permalink{$page}=$value; - push @{$meta{$page}}, scrub('<link rel="bookmark" href="'.encode_entities($value).'" />'); + $pagestate{$page}{meta}{permalink}=$value; + push @{$metaheaders{$page}}, scrub('<link rel="bookmark" href="'.encode_entities($value).'" />'); } elsif ($key eq 'stylesheet') { my $rel=exists $params{rel} ? $params{rel} : "alternate stylesheet"; @@ -123,17 +118,17 @@ sub preprocess (@) { #{{{ if (! length $stylesheet) { return "[[meta ".gettext("stylesheet not found")."]]"; } - push @{$meta{$page}}, '<link href="'.urlto($stylesheet, $page). + push @{$metaheaders{$page}}, '<link href="'.urlto($stylesheet, $page). '" rel="'.encode_entities($rel). '" title="'.encode_entities($title). "\" type=\"text/css\" />"; } elsif ($key eq 'openid') { if (exists $params{server}) { - push @{$meta{$page}}, '<link href="'.encode_entities($params{server}). + push @{$metaheaders{$page}}, '<link href="'.encode_entities($params{server}). '" rel="openid.server" />'; } - push @{$meta{$page}}, '<link href="'.encode_entities($value). + push @{$metaheaders{$page}}, '<link href="'.encode_entities($value). '" rel="openid.delegate" />'; } elsif ($key eq 'redir') { @@ -172,11 +167,11 @@ sub preprocess (@) { #{{{ if (! $safe) { $redir=scrub($redir); } - push @{$meta{$page}}, $redir; + push @{$metaheaders{$page}}, $redir; } elsif ($key eq 'link') { if (%params) { - push @{$meta{$page}}, scrub("<link href=\"".encode_entities($value)."\" ". + push @{$metaheaders{$page}}, scrub("<link href=\"".encode_entities($value)."\" ". join(" ", map { encode_entities($_)."=\"".encode_entities(decode_entities($params{$_}))."\"" } keys %params). @@ -184,7 +179,7 @@ sub preprocess (@) { #{{{ } } else { - push @{$meta{$page}}, scrub('<meta name="'.encode_entities($key). + push @{$metaheaders{$page}}, scrub('<meta name="'.encode_entities($key). '" content="'.encode_entities($value).'" />'); } @@ -197,32 +192,80 @@ sub pagetemplate (@) { #{{{ my $destpage=$params{destpage}; my $template=$params{template}; - if (exists $meta{$page} && $template->query(name => "meta")) { + if (exists $metaheaders{$page} && $template->query(name => "meta")) { # avoid duplicate meta lines my %seen; - $template->param(meta => join("\n", grep { (! $seen{$_}) && ($seen{$_}=1) } @{$meta{$page}})); + $template->param(meta => join("\n", grep { (! $seen{$_}) && ($seen{$_}=1) } @{$metaheaders{$page}})); } - if (exists $title{$page} && $template->query(name => "title")) { - $template->param(title => $title{$page}); + if (exists $pagestate{$page}{meta}{title} && $template->query(name => "title")) { + $template->param(title => $pagestate{$page}{meta}{title}); $template->param(title_overridden => 1); } - $template->param(permalink => $permalink{$page}) - if exists $permalink{$page} && $template->query(name => "permalink"); - $template->param(author => $author{$page}) - if exists $author{$page} && $template->query(name => "author"); - $template->param(authorurl => $authorurl{$page}) - if exists $authorurl{$page} && $template->query(name => "authorurl"); - if (exists $license{$page} && $template->query(name => "license") && - ($page eq $destpage || ! exists $license{$destpage} || - $license{$page} ne $license{$destpage})) { - $template->param(license => htmlize($page, $destpage, $license{$page})); + foreach my $field (qw{author authorurl permalink}) { + $template->param($field => $pagestate{$page}{meta}{$field}) + if exists $pagestate{$page}{meta}{$field} && $template->query(name => $field); } - if (exists $copyright{$page} && $template->query(name => "copyright") && - ($page eq $destpage || ! exists $copyright{$destpage} || - $copyright{$page} ne $copyright{$destpage})) { - $template->param(copyright => htmlize($page, $destpage, $copyright{$page})); + + foreach my $field (qw{license copyright}) { + if (exists $pagestate{$page}{meta}{$field} && $template->query(name => $field) && + ($page eq $destpage || ! exists $pagestate{$destpage}{meta}{$field} || + $pagestate{$page}{meta}{$field} ne $pagestate{$destpage}{meta}{$field})) { + $template->param($field => htmlize($page, $destpage, $pagestate{$page}{meta}{$field})); + } } } # }}} +sub match { #{{{ + my $field=shift; + my $page=shift; + + # turn glob into a safe regexp + my $re=quotemeta(shift); + $re=~s/\\\*/.*/g; + $re=~s/\\\?/./g; + + my $val; + if (exists $pagestate{$page}{meta}{$field}) { + $val=$pagestate{$page}{meta}{$field}; + } + elsif ($field eq 'title') { + $val=pagetitle($page); + } + + if (defined $val) { + if ($val=~/^$re$/i) { + return IkiWiki::SuccessReason->new("$re matches $field of $page"); + } + else { + return IkiWiki::FailReason->new("$re does not match $field of $page"); + } + } + else { + return IkiWiki::FailReason->new("$page does not have a $field"); + } +} #}}} + +package IkiWiki::PageSpec; + +sub match_title ($$;@) { #{{{ + IkiWiki::Plugin::meta::match("title", @_); +} #}}} + +sub match_author ($$;@) { #{{{ + IkiWiki::Plugin::meta::match("author", @_); +} #}}} + +sub match_authorurl ($$;@) { #{{{ + IkiWiki::Plugin::meta::match("authorurl", @_); +} #}}} + +sub match_license ($$;@) { #{{{ + IkiWiki::Plugin::meta::match("license", @_); +} #}}} + +sub match_copyright ($$;@) { #{{{ + IkiWiki::Plugin::meta::match("copyright", @_); +} #}}} + 1 diff --git a/IkiWiki/Plugin/prettydate.pm b/IkiWiki/Plugin/prettydate.pm index b6110e427..745e6a1de 100644 --- a/IkiWiki/Plugin/prettydate.pm +++ b/IkiWiki/Plugin/prettydate.pm @@ -63,6 +63,10 @@ sub checkconfig () { #{{{ sub IkiWiki::displaytime ($;$) { #{{{ my $time=shift; + my $format=shift; + if (! defined $format) { + $format=$config{prettydateformat}; + } eval q{use Date::Format}; error($@) if $@; @@ -93,7 +97,6 @@ sub IkiWiki::displaytime ($;$) { #{{{ $t=~s{\%A-}{my @yest=@t; $yest[6]--; strftime("%A", \@yest)}eg; - my $format=$config{prettydateformat}; $format=~s/\%X/$t/g; return strftime($format, \@t); } #}}} diff --git a/IkiWiki/Plugin/recentchanges.pm b/IkiWiki/Plugin/recentchanges.pm new file mode 100644 index 000000000..5ac0a30ef --- /dev/null +++ b/IkiWiki/Plugin/recentchanges.pm @@ -0,0 +1,116 @@ +#!/usr/bin/perl +package IkiWiki::Plugin::recentchanges; + +use warnings; +use strict; +use IkiWiki 2.00; + +sub import { #{{{ + hook(type => "checkconfig", id => "recentchanges", call => \&checkconfig); + hook(type => "refresh", id => "recentchanges", call => \&refresh); + hook(type => "htmlize", id => "_change", call => \&htmlize); +} #}}} + +sub checkconfig () { #{{{ + $config{recentchangespage}='recentchanges' unless defined $config{recentchangespage}; + $config{recentchangesnum}=100 unless defined $config{recentchangesnum}; +} #}}} + +sub refresh ($) { #{{{ + my %seen; + + # add new changes + foreach my $change (IkiWiki::rcs_recentchanges($config{recentchangesnum})) { + $seen{store($change, $config{recentchangespage})}=1; + } + + # delete old and excess changes + foreach my $page (keys %pagesources) { + if ($page=~/^\Q$config{recentchangespage}\E\/change_/ && ! $seen{$page}) { + unlink($config{srcdir}.'/'.$pagesources{$page}); + } + } +} #}}} + +# Pages with extension _change have plain html markup, pass through. +sub htmlize (@) { #{{{ + my %params=@_; + return $params{content}; +} #}}} + +sub store ($$$) { #{{{ + my $change=shift; + + my $page="$config{recentchangespage}/change_".IkiWiki::titlepage($change->{rev}); + + # Optimisation to avoid re-writing pages. Assumes commits never + # change (or that any changes are not important). + return $page if exists $pagesources{$page} && ! $config{rebuild}; + + # Limit pages to first 10, and add links to the changed pages. + my $is_excess = exists $change->{pages}[10]; + delete @{$change->{pages}}[10 .. @{$change->{pages}}] if $is_excess; + $change->{pages} = [ + map { + if (length $config{url}) { + $_->{link} = "<a href=\"$config{url}/". + urlto($_->{page},"")."\">". + IkiWiki::pagetitle($_->{page})."</a>"; + } + else { + $_->{link} = IkiWiki::pagetitle($_->{page}); + } + $_->{baseurl}="$config{url}/" if length $config{url}; + + $_; + } @{$change->{pages}} + ]; + push @{$change->{pages}}, { link => '...' } if $is_excess; + + # See if the committer is an openid. + $change->{author}=$change->{user}; + my $oiduser=IkiWiki::openiduser($change->{user}); + if (defined $oiduser) { + $change->{authorurl}=$change->{user}; + $change->{user}=$oiduser; + } + elsif (length $config{url}) { + $change->{authorurl}="$config{url}/". + (length $config{userdir} ? "$config{userdir}/" : ""). + $change->{user}; + } + + # escape wikilinks and preprocessor stuff in commit messages + if (ref $change->{message}) { + foreach my $field (@{$change->{message}}) { + if (exists $field->{line}) { + $field->{line} =~ s/(?<!\\)\[\[/\\\[\[/g; + } + } + } + + # Fill out a template with the change info. + my $template=template("change.tmpl", blind_cache => 1); + $template->param( + %$change, + commitdate => displaytime($change->{when}, "%X %x"), + wikiname => $config{wikiname}, + ); + IkiWiki::run_hooks(pagetemplate => sub { + shift->(page => $page, destpage => $page, template => $template); + }); + + my $file=$page."._change"; + writefile($file, $config{srcdir}, $template->output); + utime $change->{when}, $change->{when}, "$config{srcdir}/$file"; + + return $page; +} #}}} + +sub updatechanges ($$) { #{{{ + my $subdir=shift; + my @changes=@{shift()}; + +} #}}} + +1 diff --git a/IkiWiki/Plugin/version.pm b/IkiWiki/Plugin/version.pm index d39fd9419..f96d2df06 100644 --- a/IkiWiki/Plugin/version.pm +++ b/IkiWiki/Plugin/version.pm @@ -18,7 +18,8 @@ sub needsbuild (@) { #{{{ if ($pagestate{$page}{version}{shown} ne $IkiWiki::version) { push @$needsbuild, $pagesources{$page}; } - if (grep { $_ eq $pagesources{$page} } @$needsbuild) { + if (exists $pagesources{$page} && + grep { $_ eq $pagesources{$page} } @$needsbuild) { # remove state, will be re-added if # the version is still shown during the # rebuild |