%forcerebuild %loaded_plugins};
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
htmllink readfile writefile pagetype srcfile pagename
displaytime will_render gettext urlto targetpage
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 (@) {
my $deptype=0;
foreach my $type (@_) {
}
sub pagespec_match_list ($$;@) {
- my $pages=shift;
- my $spec=shift;
- my @params=@_;
+ my $page=shift;
+ my $pagespec=shift;
+ my %params=@_;
- my $sub=pagespec_translate($spec);
- error "syntax error in pagespec \"$spec\""
+ # Backwards compatability with old calling convention.
+ if (ref $page) {
+ print STDERR "warning: a plugin (".caller().") is using pagespec_match_list in an obsolete way, and needs to be updated\n";
+ $params{list}=$page;
+ $page=$params{location}; # ugh!
+ }
+
+ 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 @ret;
- my $r;
- foreach my $page (@$pages) {
- $r=$sub->($page, @params);
- push @ret, $page if $r;
+ 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);
- if (! @ret && defined $r && $r->isa("IkiWiki::ErrorReason")) {
- error(sprintf(gettext("cannot match pages: %s"), $r));
+ 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};
+ }
+ }
}
- else {
- return @ret;
+ 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 ($) {
my $nyear = $params{nyear};
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
# month calendar when pages are added/removed
deptype => deptype("presence"))) {
$num+=$params{skip};
}
- @list = use_pagespec($params{page}, $params{pages},
+ @list = pagespec_match_list($params{page}, $params{pages},
deptype => deptype($quick ? "presence" : "content"),
limit => sub { $_[0] ne $params{page} },
sort => exists $params{sort} ? $params{sort} : "age",
}
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"),
- list => \@feedlist);
+ list => \@feedlist,
+ );
}
my ($feedbase, $feednum);
# Get all the items to map.
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} &&
exists $pagestate{$page} &&
exists $pagestate{$page}{meta}{$params{show}}) {
# considering as orphans.
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
deptype => deptype("presence"),
limit => sub {
return scalar keys %pagesources;
}
- return scalar use_pagespec($params{page}, $pages,
+ return scalar pagespec_match_list($params{page}, $pages,
deptype => deptype("presence"));
}
my %counts;
my $max = 0;
- foreach my $page (use_pagespec($params{page}, $params{pages},
- # update when a displayed page is added or removed
- deptype => deptype("presence"))) {
+ foreach my $page (pagespec_match_list($params{page}, $params{pages},
+ # update when a displayed page is added/removed
+ deptype => deptype("presence"))) {
use IkiWiki::Render;
my @backlinks = IkiWiki::backlink_pages($page);
if (exists $params{among}) {
# 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
deptype => deptype("links"),
list => \@backlinks
}
my @list=sort { $params{timehash}->{$b} <=> $params{timehash}->{$a} }
- use_pagespec($params{page}, $params{pages},
+ pagespec_match_list($params{page}, $params{pages},
deptype => $deptype,
limit => sub { $_[0] ne $params{page} },
);
info.
* Plugins providing PageSpec `match_*` functions should pass additional
influence information when creating result objects.
- * Added `use_pagespec` function, that plugins can use to find a list
- of matching pages and add dependencies and influences, all at once,
- and efficiently.
+ * API change: `pagespec_match_list` has completly changed its interface.
+ The old interface will be removed soon, and a warning will be printed
+ if any plugins try to use it.
* Optimize away most expensive file prune calls, when refreshing,
by only checking new files.
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
in the wiki that match the [[ikiwiki/PageSpec]].
The page will automatically be made to depend on the specified
[[ikiwiki/PageSpec]], so `add_depends` does not need to be called. This
-is significantly more efficient than calling `add_depends`
-followed by `pagespec_match_list`. You should use this anytime a plugin
-needs to match a set of pages and generate something based on that list.
+is significantly more efficient than calling `add_depends` and
+`pagespec_match` in a loop. You should use this anytime a plugin
+needs to match a set of pages and do something based on that list.
Additional named parameters can be specified:
* `list` makes it only match amoung the specified list of pages.
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($$;$)`
Makes the specified page depend on the specified [[ikiwiki/PageSpec]].
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
--- /dev/null
+#!/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");
+++ /dev/null
-#!/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");