rename use_pagespec to pagespec_match_list

To avoid breaking plugins, also support the old pagespec_match_list
calling convention, with a deprecation warning.
master
Joey Hess 2009-10-08 23:51:06 -04:00
parent 955bcea2a7
commit 5e7b2dea84
12 changed files with 141 additions and 164 deletions

View File

@ -17,7 +17,7 @@ use vars qw{%config %links %oldlinks %pagemtime %pagectime %pagecase
%forcerebuild %loaded_plugins}; %forcerebuild %loaded_plugins};
use Exporter q{import}; use Exporter q{import};
our @EXPORT = qw(hook debug error template htmlpage deptype use_pagespec our @EXPORT = qw(hook debug error template htmlpage deptype
add_depends pagespec_match pagespec_match_list bestlink add_depends pagespec_match pagespec_match_list bestlink
htmllink readfile writefile pagetype srcfile pagename htmllink readfile writefile pagetype srcfile pagename
displaytime will_render gettext urlto targetpage displaytime will_render gettext urlto targetpage
@ -1798,91 +1798,6 @@ sub add_depends ($$;$) {
return 1; return 1;
} }
sub use_pagespec ($$;@) {
my $page=shift;
my $pagespec=shift;
my %params=@_;
my $sub=pagespec_translate($pagespec);
error "syntax error in pagespec \"$pagespec\""
if $@ || ! defined $sub;
my @candidates;
if (exists $params{limit}) {
@candidates=grep { $params{limit}->($_) } keys %pagesources;
}
else {
@candidates=keys %pagesources;
}
if (defined $params{sort}) {
my $f;
if ($params{sort} eq 'title') {
$f=sub { pagetitle(basename($a)) cmp pagetitle(basename($b)) };
}
elsif ($params{sort} eq 'title_natural') {
eval q{use Sort::Naturally};
if ($@) {
error(gettext("Sort::Naturally needed for title_natural sort"));
}
$f=sub { Sort::Naturally::ncmp(pagetitle(basename($a)), pagetitle(basename($b))) };
}
elsif ($params{sort} eq 'mtime') {
$f=sub { $pagemtime{$b} <=> $pagemtime{$a} };
}
elsif ($params{sort} eq 'age') {
$f=sub { $pagectime{$b} <=> $pagectime{$a} };
}
else {
error sprintf(gettext("unknown sort type %s"), $params{sort});
}
@candidates = sort { &$f } @candidates;
}
@candidates=reverse(@candidates) if $params{reverse};
my @matches;
my $firstfail;
my $count=0;
foreach my $p (@candidates) {
my $r=$sub->($p, location => $page);
if ($r) {
push @matches, [$p, $r];
last if defined $params{num} && ++$count == $params{num};
}
elsif (! defined $firstfail) {
$firstfail=$r;
}
}
$depends{$page}{$pagespec} |= ($params{deptype} || $DEPEND_CONTENT);
my @ret;
if (@matches) {
# Add all influences from successful matches.
foreach my $m (@matches) {
push @ret, $m->[0];
my %i=$m->[1]->influences;
foreach my $i (keys %i) {
$depends_simple{$page}{lc $i} |= $i{$i};
}
}
}
elsif (defined $firstfail) {
# Add influences from one failure. (Which one should not
# matter; all should have the same influences.)
my %i=$firstfail->influences;
foreach my $i (keys %i) {
$depends_simple{$page}{lc $i} |= $i{$i};
}
error(sprintf(gettext("cannot match pages: %s"), $firstfail))
if $firstfail->isa("IkiWiki::ErrorReason");
}
return @ret;
}
sub deptype (@) { sub deptype (@) {
my $deptype=0; my $deptype=0;
foreach my $type (@_) { foreach my $type (@_) {
@ -2055,27 +1970,95 @@ sub pagespec_match ($$;@) {
} }
sub pagespec_match_list ($$;@) { sub pagespec_match_list ($$;@) {
my $pages=shift; my $page=shift;
my $spec=shift; my $pagespec=shift;
my @params=@_; my %params=@_;
my $sub=pagespec_translate($spec); # Backwards compatability with old calling convention.
error "syntax error in pagespec \"$spec\"" if (ref $page) {
if $@ || ! defined $sub; print STDERR "warning: a plugin (".caller().") is using pagespec_match_list in an obsolete way, and needs to be updated\n";
$params{list}=$page;
my @ret; $page=$params{location}; # ugh!
my $r;
foreach my $page (@$pages) {
$r=$sub->($page, @params);
push @ret, $page if $r;
} }
if (! @ret && defined $r && $r->isa("IkiWiki::ErrorReason")) { my $sub=pagespec_translate($pagespec);
error(sprintf(gettext("cannot match pages: %s"), $r)); error "syntax error in pagespec \"$pagespec\""
if $@ || ! defined $sub;
my @candidates;
if (exists $params{limit}) {
@candidates=grep { $params{limit}->($_) } keys %pagesources;
} }
else { else {
return @ret; @candidates=keys %pagesources;
} }
if (defined $params{sort}) {
my $f;
if ($params{sort} eq 'title') {
$f=sub { pagetitle(basename($a)) cmp pagetitle(basename($b)) };
}
elsif ($params{sort} eq 'title_natural') {
eval q{use Sort::Naturally};
if ($@) {
error(gettext("Sort::Naturally needed for title_natural sort"));
}
$f=sub { Sort::Naturally::ncmp(pagetitle(basename($a)), pagetitle(basename($b))) };
}
elsif ($params{sort} eq 'mtime') {
$f=sub { $pagemtime{$b} <=> $pagemtime{$a} };
}
elsif ($params{sort} eq 'age') {
$f=sub { $pagectime{$b} <=> $pagectime{$a} };
}
else {
error sprintf(gettext("unknown sort type %s"), $params{sort});
}
@candidates = sort { &$f } @candidates;
}
@candidates=reverse(@candidates) if $params{reverse};
my @matches;
my $firstfail;
my $count=0;
foreach my $p (@candidates) {
my $r=$sub->($p, location => $page);
if ($r) {
push @matches, [$p, $r];
last if defined $params{num} && ++$count == $params{num};
}
elsif (! defined $firstfail) {
$firstfail=$r;
}
}
$depends{$page}{$pagespec} |= ($params{deptype} || $DEPEND_CONTENT);
my @ret;
if (@matches) {
# Add all influences from successful matches.
foreach my $m (@matches) {
push @ret, $m->[0];
my %i=$m->[1]->influences;
foreach my $i (keys %i) {
$depends_simple{$page}{lc $i} |= $i{$i};
}
}
}
elsif (defined $firstfail) {
# Add influences from one failure. (Which one should not
# matter; all should have the same influences.)
my %i=$firstfail->influences;
foreach my $i (keys %i) {
$depends_simple{$page}{lc $i} |= $i{$i};
}
error(sprintf(gettext("cannot match pages: %s"), $firstfail))
if $firstfail->isa("IkiWiki::ErrorReason");
}
return @ret;
} }
sub pagespec_valid ($) { sub pagespec_valid ($) {

View File

@ -74,7 +74,7 @@ sub format_month (@) {
my $nyear = $params{nyear}; my $nyear = $params{nyear};
my %linkcache; my %linkcache;
foreach my $p (use_pagespec($params{page}, $params{pagespec}, foreach my $p (pagespec_match_list($params{page}, $params{pagespec},
# add presence dependencies to update # add presence dependencies to update
# month calendar when pages are added/removed # month calendar when pages are added/removed
deptype => deptype("presence"))) { deptype => deptype("presence"))) {

View File

@ -216,7 +216,7 @@ sub preprocess_inline (@) {
$num+=$params{skip}; $num+=$params{skip};
} }
@list = use_pagespec($params{page}, $params{pages}, @list = pagespec_match_list($params{page}, $params{pages},
deptype => deptype($quick ? "presence" : "content"), deptype => deptype($quick ? "presence" : "content"),
limit => sub { $_[0] ne $params{page} }, limit => sub { $_[0] ne $params{page} },
sort => exists $params{sort} ? $params{sort} : "age", sort => exists $params{sort} ? $params{sort} : "age",
@ -245,9 +245,11 @@ sub preprocess_inline (@) {
} }
if ($feeds && exists $params{feedpages}) { if ($feeds && exists $params{feedpages}) {
@feedlist = use_pagespec($params{page}, "($params{pages}) and ($params{feedpages})", @feedlist = pagespec_match_list(
$params{page}, "($params{pages}) and ($params{feedpages})",
deptype => deptype($quick ? "presence" : "content"), deptype => deptype($quick ? "presence" : "content"),
list => \@feedlist); list => \@feedlist,
);
} }
my ($feedbase, $feednum); my ($feedbase, $feednum);

View File

@ -36,7 +36,8 @@ sub preprocess (@) {
# Get all the items to map. # Get all the items to map.
my %mapitems; my %mapitems;
foreach my $page (use_pagespec($params{page}, $params{pages}, deptype => $deptype)) { foreach my $page (pagespec_match_list($params{page}, $params{pages},
deptype => $deptype)) {
if (exists $params{show} && if (exists $params{show} &&
exists $pagestate{$page} && exists $pagestate{$page} &&
exists $pagestate{$page}{meta}{$params{show}}) { exists $pagestate{$page}{meta}{$params{show}}) {

View File

@ -28,7 +28,7 @@ sub preprocess (@) {
# considering as orphans. # considering as orphans.
add_depends($params{page}, "*", deptype("links")); add_depends($params{page}, "*", deptype("links"));
my @orphans=use_pagespec($params{page}, $params{pages}, my @orphans=pagespec_match_list($params{page}, $params{pages},
# update when orphans are added/removed # update when orphans are added/removed
deptype => deptype("presence"), deptype => deptype("presence"),
limit => sub { limit => sub {

View File

@ -32,7 +32,7 @@ sub preprocess (@) {
return scalar keys %pagesources; return scalar keys %pagesources;
} }
return scalar use_pagespec($params{page}, $pages, return scalar pagespec_match_list($params{page}, $pages,
deptype => deptype("presence")); deptype => deptype("presence"));
} }

View File

@ -37,16 +37,17 @@ sub preprocess (@) {
my %counts; my %counts;
my $max = 0; my $max = 0;
foreach my $page (use_pagespec($params{page}, $params{pages}, foreach my $page (pagespec_match_list($params{page}, $params{pages},
# update when a displayed page is added or removed # update when a displayed page is added/removed
deptype => deptype("presence"))) { deptype => deptype("presence"))) {
use IkiWiki::Render; use IkiWiki::Render;
my @backlinks = IkiWiki::backlink_pages($page); my @backlinks = IkiWiki::backlink_pages($page);
if (exists $params{among}) { if (exists $params{among}) {
# only consider backlinks from the amoung pages # only consider backlinks from the amoung pages
@backlinks = use_pagespec($params{page}, $params{among}, @backlinks = pagespec_match_list(
$params{page}, $params{among},
# update whenever links on those pages change # update whenever links on those pages change
deptype => deptype("links"), deptype => deptype("links"),
list => \@backlinks list => \@backlinks

View File

@ -54,7 +54,7 @@ sub preprocess (@) {
} }
my @list=sort { $params{timehash}->{$b} <=> $params{timehash}->{$a} } my @list=sort { $params{timehash}->{$b} <=> $params{timehash}->{$a} }
use_pagespec($params{page}, $params{pages}, pagespec_match_list($params{page}, $params{pages},
deptype => $deptype, deptype => $deptype,
limit => sub { $_[0] ne $params{page} }, limit => sub { $_[0] ne $params{page} },
); );

6
debian/changelog vendored
View File

@ -33,9 +33,9 @@ ikiwiki (3.14159266) UNRELEASED; urgency=low
info. info.
* Plugins providing PageSpec `match_*` functions should pass additional * Plugins providing PageSpec `match_*` functions should pass additional
influence information when creating result objects. influence information when creating result objects.
* Added `use_pagespec` function, that plugins can use to find a list * API change: `pagespec_match_list` has completly changed its interface.
of matching pages and add dependencies and influences, all at once, The old interface will be removed soon, and a warning will be printed
and efficiently. if any plugins try to use it.
* Optimize away most expensive file prune calls, when refreshing, * Optimize away most expensive file prune calls, when refreshing,
by only checking new files. by only checking new files.

View File

@ -625,16 +625,16 @@ dependency type from one or more of these keywords:
If multiple types are specified, they are combined. If multiple types are specified, they are combined.
#### `use_pagespec($$;@)` #### `pagespec_match_list($$;@)`
Passed a page name, and [[ikiwiki/PageSpec]], returns a list of pages Passed a page name, and [[ikiwiki/PageSpec]], returns a list of pages
in the wiki that match the [[ikiwiki/PageSpec]]. in the wiki that match the [[ikiwiki/PageSpec]].
The page will automatically be made to depend on the specified The page will automatically be made to depend on the specified
[[ikiwiki/PageSpec]], so `add_depends` does not need to be called. This [[ikiwiki/PageSpec]], so `add_depends` does not need to be called. This
is significantly more efficient than calling `add_depends` is significantly more efficient than calling `add_depends` and
followed by `pagespec_match_list`. You should use this anytime a plugin `pagespec_match` in a loop. You should use this anytime a plugin
needs to match a set of pages and generate something based on that list. needs to match a set of pages and do something based on that list.
Additional named parameters can be specified: Additional named parameters can be specified:
@ -650,6 +650,9 @@ Additional named parameters can be specified:
* `list` makes it only match amoung the specified list of pages. * `list` makes it only match amoung the specified list of pages.
Default is to match amoung all pages in the wiki. Default is to match amoung all pages in the wiki.
Unlike pagespec_match, this may throw an error if there is an error in
the pagespec.
#### `add_depends($$;$)` #### `add_depends($$;$)`
Makes the specified page depend on the specified [[ikiwiki/PageSpec]]. Makes the specified page depend on the specified [[ikiwiki/PageSpec]].
@ -672,19 +675,6 @@ The most often used is "location", which specifies the location the
PageSpec should match against. If not passed, relative PageSpecs will match PageSpec should match against. If not passed, relative PageSpecs will match
relative to the top of the wiki. 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($$)` #### `bestlink($$)`
Given a page and the text of a link on the page, determine which Given a page and the text of a link on the page, determine which

View File

@ -0,0 +1,31 @@
#!/usr/bin/perl
use warnings;
use strict;
use Test::More tests => 10;
BEGIN { use_ok("IkiWiki"); }
%pagesources=(
foo => "foo.mdwn",
bar => "bar.mdwn",
"post/1" => "post/1.mdwn",
"post/2" => "post/2.mdwn",
"post/3" => "post/3.mdwn",
);
is_deeply([pagespec_match_list("foo", "bar")], ["bar"]);
is_deeply([sort(pagespec_match_list("foo", "post/*"))], ["post/1", "post/2", "post/3"]);
is_deeply([pagespec_match_list("foo", "post/*", sort => "title", reverse => 1)],
["post/3", "post/2", "post/1"]);
is_deeply([pagespec_match_list("foo", "post/*", sort => "title", num => 2)],
["post/1", "post/2"]);
is_deeply([pagespec_match_list("foo", "post/*", sort => "title", num => 50)],
["post/1", "post/2", "post/3"]);
is_deeply([pagespec_match_list("foo", "post/*", sort => "title",
limit => sub { $_[0] !~ /3/}) ],
["post/1", "post/2"]);
my $r=eval { pagespec_match_list("foo", "beep") };
ok(eval { pagespec_match_list("foo", "beep") } == 0);
ok(! $@, "does not fail with error when unable to match anything");
eval { pagespec_match_list("foo", "this is not a legal pagespec!") };
ok($@, "fails with error when pagespec bad");

View File

@ -1,31 +0,0 @@
#!/usr/bin/perl
use warnings;
use strict;
use Test::More tests => 10;
BEGIN { use_ok("IkiWiki"); }
%pagesources=(
foo => "foo.mdwn",
bar => "bar.mdwn",
"post/1" => "post/1.mdwn",
"post/2" => "post/2.mdwn",
"post/3" => "post/3.mdwn",
);
is_deeply([use_pagespec("foo", "bar")], ["bar"]);
is_deeply([sort(use_pagespec("foo", "post/*"))], ["post/1", "post/2", "post/3"]);
is_deeply([use_pagespec("foo", "post/*", sort => "title", reverse => 1)],
["post/3", "post/2", "post/1"]);
is_deeply([use_pagespec("foo", "post/*", sort => "title", num => 2)],
["post/1", "post/2"]);
is_deeply([use_pagespec("foo", "post/*", sort => "title", num => 50)],
["post/1", "post/2", "post/3"]);
is_deeply([use_pagespec("foo", "post/*", sort => "title",
limit => sub { $_[0] !~ /3/}) ],
["post/1", "post/2"]);
my $r=eval { use_pagespec("foo", "beep") };
ok(eval { use_pagespec("foo", "beep") } == 0);
ok(! $@, "does not fail with error when unable to match anything");
eval { use_pagespec("foo", "this is not a legal pagespec!") };
ok($@, "fails with error when pagespec bad");