pagespec_match_list added and used in most appropriate places

* pagespec_match_list: New API function, matches pages in a list
  and throws an error if the pagespec is bad.
* inline, brokenlinks, calendar, linkmap, map, orphans, pagecount,
  pagestate, postsparkline: Display a handy error message if the pagespec
  is erronious.
master
Joey Hess 2009-04-23 15:45:30 -04:00
parent 527d178c12
commit aa306957ba
13 changed files with 111 additions and 86 deletions

View File

@ -18,10 +18,10 @@ use vars qw{%config %links %oldlinks %pagemtime %pagectime %pagecase
use Exporter q{import};
our @EXPORT = qw(hook debug error template htmlpage add_depends pagespec_match
bestlink htmllink readfile writefile pagetype srcfile pagename
displaytime will_render gettext urlto targetpage
add_underlay pagetitle titlepage linkpage newpagefile
inject
pagespec_match_list bestlink htmllink readfile writefile
pagetype srcfile pagename displaytime will_render gettext urlto
targetpage add_underlay pagetitle titlepage linkpage
newpagefile inject
%config %links %pagestate %wikistate %renderedfiles
%pagesources %destsources);
our $VERSION = 3.00; # plugin interface version, next is ikiwiki version
@ -1832,6 +1832,30 @@ sub pagespec_match ($$;@) {
return $sub->($page, @params);
}
sub pagespec_match_list ($$;@) {
my $pages=shift;
my $spec=shift;
my @params=@_;
my $sub=pagespec_translate($spec);
error "syntax error in pagespec \"$spec\""
if $@ || ! defined $sub;
my @ret;
my $r;
foreach my $page (@$pages) {
$r=$sub->($page, @params);
push @ret, $page if $r;
}
if (! @ret && defined $r && $r->isa("IkiWiki::ErrorReason")) {
error(sprintf(gettext("cannot match pages: %s"), $r));
}
else {
return @ret;
}
}
sub pagespec_valid ($) {
my $spec=shift;

View File

@ -28,18 +28,17 @@ sub preprocess (@) {
add_depends($params{page}, $params{pages});
my %broken;
foreach my $page (keys %links) {
if (pagespec_match($page, $params{pages}, location => $params{page})) {
my $discussion=gettext("discussion");
my %seen;
foreach my $link (@{$links{$page}}) {
next if $seen{$link};
$seen{$link}=1;
next if $link =~ /.*\/\Q$discussion\E/i && $config{discussion};
my $bestlink=bestlink($page, $link);
next if length $bestlink;
push @{$broken{$link}}, $page;
}
foreach my $page (pagespec_match_list([keys %links],
$params{pages}, location => $params{page})) {
my $discussion=gettext("discussion");
my %seen;
foreach my $link (@{$links{$page}}) {
next if $seen{$link};
$seen{$link}=1;
next if $link =~ /.*\/\Q$discussion\E/i && $config{discussion};
my $bestlink=bestlink($page, $link);
next if length $bestlink;
push @{$broken{$link}}, $page;
}
}

View File

@ -369,8 +369,7 @@ sub preprocess (@) {
my $page =$params{page};
if (! defined $cache{$pagespec}) {
foreach my $p (keys %pagesources) {
next unless pagespec_match($p, $pagespec);
foreach my $p (pagespec_match_list([keys %pagesources], $pagespec)) {
my $mtime = $IkiWiki::pagectime{$p};
my $src = $pagesources{$p};
my @date = localtime($mtime);

View File

@ -230,10 +230,17 @@ sub hook ($@) {
}
sub pagespec_match ($@) {
# convert pagespec_match's return object into a XML RPC boolean
# convert return object into a XML RPC boolean
my $plugin=shift;
return RPC::XML::boolean->new(0 + IkiWiki::pagespec_march(@_));
}
sub pagespec_match_list ($@) {
# convert return object into a XML RPC boolean
my $plugin=shift;
return RPC::XML::boolean->new(0 + IkiWiki::pagespec_march_list(@_));
}
1

View File

@ -183,20 +183,9 @@ sub preprocess_inline (@) {
$params{template} = $archive ? "archivepage" : "inlinepage";
}
my @list;
my $lastmatch;
foreach my $page (keys %pagesources) {
next if $page eq $params{page};
$lastmatch=pagespec_match($page, $params{pages}, location => $params{page});
if ($lastmatch) {
push @list, $page;
}
}
if (! @list && defined $lastmatch &&
$lastmatch->isa("IkiWiki::ErrorReason")) {
error(sprintf(gettext("cannot match pages: %s"), $lastmatch));
}
my @list=pagespec_match_list(
[ grep { $_ ne $params{page}} keys %pagesources ],
$params{pages}, location => $params{page});
if (exists $params{sort} && $params{sort} eq 'title') {
@list=sort { pagetitle(basename($a)) cmp pagetitle(basename($b)) } @list;

View File

@ -56,10 +56,9 @@ sub genmap ($) {
# Get all the items to map.
my %mapitems = ();
foreach my $item (keys %links) {
if (pagespec_match($item, $params{pages}, location => $params{page})) {
$mapitems{$item}=urlto($item, $params{destpage});
}
foreach my $item (pagespec_match_list([keys %links],
$params{pages}, location => $params{page})) {
$mapitems{$item}=urlto($item, $params{destpage});
}
my $dest=$params{page}."/linkmap.png";

View File

@ -32,32 +32,31 @@ sub preprocess (@) {
# Get all the items to map.
my %mapitems;
foreach my $page (keys %pagesources) {
if (pagespec_match($page, $params{pages}, location => $params{page})) {
if (exists $params{show} &&
exists $pagestate{$page} &&
exists $pagestate{$page}{meta}{$params{show}}) {
$mapitems{$page}=$pagestate{$page}{meta}{$params{show}};
}
else {
$mapitems{$page}='';
}
# Check for a common prefix.
if (! defined $common_prefix) {
$common_prefix=$page;
}
elsif (length $common_prefix &&
$page !~ /^\Q$common_prefix\E(\/|$)/) {
my @a=split(/\//, $page);
my @b=split(/\//, $common_prefix);
$common_prefix="";
while (@a && @b && $a[0] eq $b[0]) {
if (length $common_prefix) {
$common_prefix.="/";
}
$common_prefix.=shift(@a);
shift @b;
foreach my $page (pagespec_match_list([keys %pagesources],
$params{pages}, location => $params{page})) {
if (exists $params{show} &&
exists $pagestate{$page} &&
exists $pagestate{$page}{meta}{$params{show}}) {
$mapitems{$page}=$pagestate{$page}{meta}{$params{show}};
}
else {
$mapitems{$page}='';
}
# Check for a common prefix.
if (! defined $common_prefix) {
$common_prefix=$page;
}
elsif (length $common_prefix &&
$page !~ /^\Q$common_prefix\E(\/|$)/) {
my @a=split(/\//, $page);
my @b=split(/\//, $common_prefix);
$common_prefix="";
while (@a && @b && $a[0] eq $b[0]) {
if (length $common_prefix) {
$common_prefix.="/";
}
$common_prefix.=shift(@a);
shift @b;
}
}
}

View File

@ -35,9 +35,10 @@ sub preprocess (@) {
my @orphans;
my $discussion=gettext("discussion");
foreach my $page (keys %pagesources) {
next if $linkedto{$page} || $page eq 'index';
next unless pagespec_match($page, $params{pages}, location => $params{page});
foreach my $page (pagespec_match_list(
[ grep { ! $linkedto{$_} && $_ ne 'index' }
keys %pagesources ],
$params{pages}, location => $params{page})) {
# If the page has a link to some other page, it's
# indirectly linked to a page via that page's backlinks.
next if grep {

View File

@ -27,12 +27,9 @@ sub preprocess (@) {
add_depends($params{page}, $params{pages});
my @pages=keys %pagesources;
return $#pages+1 if $params{pages} eq "*"; # optimisation
my $count=0;
foreach my $page (@pages) {
$count++ if pagespec_match($page, $params{pages}, location => $params{page});
}
return $count;
@pages=pagespec_match_list(\@pages, $params{pages}, location => $params{page})
if $params{pages} ne "*"; # optimisation;
return $#pages+1;
}
1

View File

@ -41,12 +41,11 @@ sub preprocess (@) {
my %counts;
my $max = 0;
foreach my $page (keys %links) {
if (pagespec_match($page, $params{pages}, location => $params{page})) {
use IkiWiki::Render;
$counts{$page} = scalar(IkiWiki::backlinks($page));
$max = $counts{$page} if $counts{$page} > $max;
}
foreach my $page (pagespec_match_list([keys %links],
$params{pages}, location => $params{page})) {
use IkiWiki::Render;
$counts{$page} = scalar(IkiWiki::backlinks($page));
$max = $counts{$page} if $counts{$page} > $max;
}
if ($style eq 'table') {

View File

@ -50,13 +50,9 @@ sub preprocess (@) {
add_depends($params{page}, $params{pages});
my @list;
foreach my $page (keys %pagesources) {
next if $page eq $params{page};
if (pagespec_match($page, $params{pages}, location => $params{page})) {
push @list, $page;
}
}
my @list=pagespec_match_list(
[ grep { $_ ne $params{page} } keys %pagesources],
$params{pages}, location => $params{page});
@list = sort { $params{timehash}->{$b} <=> $params{timehash}->{$a} } @list;

7
debian/changelog vendored
View File

@ -11,8 +11,11 @@ ikiwiki (3.11) UNRELEASED; urgency=low
* Add IkiWiki::ErrorReason objects, and modify pagespecs to return
them in cases where they fail to match due to a configuration or syntax
error.
* inline: Display a handy error message if the inline cannot display any
pages due to such an error.
* pagespec_match_list: New API function, matches pages in a list
and throws an error if the pagespec is bad.
* inline, brokenlinks, calendar, linkmap, map, orphans, pagecount,
pagestate, postsparkline: Display a handy error message if the pagespec
is erronious.
* comments: Add link to comment post form to allow user to sign in
if they wish to, if the configuration makes signin optional
for commenting.

View File

@ -572,6 +572,19 @@ The most often used is "location", which specifies the location the
PageSpec should match against. If not passed, relative PageSpecs will match
relative to the top of the wiki.
#### `pagespec_match_list($$;@)`
Passed a reference to a list of page names, and [[ikiwiki/PageSpec]],
returns the set of pages that match the [[ikiwiki/PageSpec]].
Additional named parameters can be passed, to further limit the match.
The most often used is "location", which specifies the location the
PageSpec should match against. If not passed, relative PageSpecs will match
relative to the top of the wiki.
Unlike pagespec_match, this may throw an error if there is an error in
the pagespec.
#### `bestlink($$)`
Given a page and the text of a link on the page, determine which