* Renamed GlobLists to PageSpecs.
authorjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Wed, 2 Aug 2006 00:14:31 +0000 (00:14 +0000)
committerjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Wed, 2 Aug 2006 00:14:31 +0000 (00:14 +0000)
* PageSpecs can now include nested parens, "and", and "or". This remains
  backwards compatible to the old GlobList format. It's implemented by
  treating the GlobList as a very limited microlanguage that is transformed
  to perl code that does the matching.
* The old GlobList format is deprecated, and I encourage users to switch to
  using the new PageSpec format. Compatability with the old format will be
  removed at some point, possibly by 2.0.
* Wiki rebuild needed on upgrade to this version due to PageSpec change.
* Add support for creation_month and creation_year to PageSpec.
  Closes: #380680
* Changes to index file encoding.

36 files changed:
IkiWiki.pm
IkiWiki/CGI.pm
IkiWiki/Plugin/aggregate.pm
IkiWiki/Plugin/brokenlinks.pm
IkiWiki/Plugin/inline.pm
IkiWiki/Plugin/orphans.pm
IkiWiki/Plugin/pagecount.pm
IkiWiki/Plugin/pagestats.pm
IkiWiki/Render.pm
IkiWiki/UserInfo.pm
basewiki/blog.mdwn
basewiki/globlist.mdwn [deleted file]
basewiki/pagespec.mdwn [new file with mode: 0644]
debian/NEWS
debian/changelog
debian/postinst
doc/bugs.mdwn
doc/bugs/done.mdwn
doc/bugs/inline_page_not_updated_on_removal.mdwn
doc/features.mdwn
doc/install.mdwn
doc/news.mdwn
doc/patchqueue.mdwn
doc/plugins/brokenlinks.mdwn
doc/plugins/orphans.mdwn
doc/plugins/pagecount.mdwn
doc/plugins/tag.mdwn
doc/plugins/write.mdwn
doc/roadmap.mdwn
doc/todo.mdwn
doc/todo/done.mdwn
doc/todo/improve_globlists.mdwn
doc/todo/multiple_templates.mdwn
t/globlist_match.t [deleted file]
t/pagespec_match.t [new file with mode: 0755]
t/pagespec_merge.t [moved from t/globlist_merge.t with 86% similarity]

index 2face7082dc78e9be743fb65a91f29d36c56524b..7ead13cf66e054fc54b9efd30929a8155c69b010 100644 (file)
@@ -4,6 +4,7 @@ package IkiWiki;
 use warnings;
 use strict;
 use Encode;
+use HTML::Entities;
 use open qw{:utf8 :std};
 
 # Optimisation.
@@ -290,7 +291,7 @@ sub styleurl (;$) { #{{{
        return $page."style.css";
 } #}}}
 
-sub abs2rel ($$) {
+sub abs2rel ($$) { #{{{
        # Work around very innefficient behavior in File::Spec if abs2rel
        # is passed two relative paths. It's much faster if paths are
        # absolute!
@@ -301,7 +302,7 @@ sub abs2rel ($$) {
        my $ret=File::Spec->abs2rel($path, $base);
        $ret=~s/^// if defined $ret;
        return $ret;
-}
+} #}}}
 
 sub htmllink ($$$;$$$) { #{{{
        my $lpage=shift; # the page doing the linking
@@ -380,7 +381,7 @@ sub loadindex () { #{{{
                $items{link}=[];
                foreach my $i (split(/ /, $_)) {
                        my ($item, $val)=split(/=/, $i, 2);
-                       push @{$items{$item}}, $val;
+                       push @{$items{$item}}, decode_entities($val);
                }
 
                next unless exists $items{src}; # skip bad lines for now
@@ -391,8 +392,7 @@ sub loadindex () { #{{{
                        $oldpagemtime{$page}=$items{mtime}[0];
                        $oldlinks{$page}=[@{$items{link}}];
                        $links{$page}=[@{$items{link}}];
-                       $depends{$page}=join(" ", @{$items{depends}})
-                               if exists $items{depends};
+                       $depends{$page}=$items{depends}[0] if exists $items{depends};
                        $renderedfiles{$page}=$items{dest}[0];
                }
                $pagectime{$page}=$items{ctime}[0];
@@ -416,7 +416,7 @@ sub saveindex () { #{{{
                        "dest=$renderedfiles{$page}";
                $line.=" link=$_" foreach @{$links{$page}};
                if (exists $depends{$page}) {
-                       $line.=" depends=$_" foreach split " ", $depends{$page};
+                       $line.=" depends=".encode_entities($depends{$page}, " \t\n");
                }
                print OUT $line."\n";
        }
@@ -454,49 +454,6 @@ sub misctemplate ($$) { #{{{
        return $template->output;
 }#}}}
 
-sub glob_match ($$) { #{{{
-       my $page=shift;
-       my $glob=shift;
-
-       if ($glob =~ /^link\((.+)\)$/) {
-               my $rev = $links{$page} or return undef;
-               foreach my $p (@$rev) {
-                       return 1 if lc $p eq $1;
-               }
-               return 0;
-       } elsif ($glob =~ /^backlink\((.+)\)$/) {
-               my $rev = $links{$1} or return undef;
-               foreach my $p (@$rev) {
-                       return 1 if lc $p eq $page;
-               }
-               return 0;
-       } else {
-               # turn glob into safe regexp
-               $glob=quotemeta($glob);
-               $glob=~s/\\\*/.*/g;
-               $glob=~s/\\\?/./g;
-               $glob=~s!\\/!/!g;
-               
-               return $page=~/^$glob$/i;
-       }
-} #}}}
-
-sub globlist_match ($$) { #{{{
-       my $page=shift;
-       my @globlist=split(" ", shift);
-
-       # check any negated globs first
-       foreach my $glob (@globlist) {
-               return 0 if $glob=~/^!(.*)/ && glob_match($page, $1);
-       }
-
-       foreach my $glob (@globlist) {
-               return 1 if glob_match($page, $glob);
-       }
-       
-       return 0;
-} #}}}
-
 sub hook (@) { # {{{
        my %param=@_;
        
@@ -520,4 +477,136 @@ sub run_hooks ($$) { # {{{
        }
 } #}}}
 
+sub globlist_to_pagespec ($) { #{{{
+       my @globlist=split(' ', shift);
+
+       my (@spec, @skip);
+       foreach my $glob (@globlist) {
+               if ($glob=~/^!(.*)/) {
+                       push @skip, $glob;
+               }
+               else {
+                       push @spec, $glob;
+               }
+       }
+
+       my $spec=join(" or ", @spec);
+       if (@skip) {
+               my $skip=join(" and ", @skip);
+               if (length $spec) {
+                       $spec="$skip and ($spec)";
+               }
+               else {
+                       $spec=$skip;
+               }
+       }
+       return $spec;
+} #}}}
+
+sub is_globlist ($) { #{{{
+       my $s=shift;
+       $s=~/[^\s]+\s+([^\s]+)/ && $1 ne "and" && $1 ne "or";
+} #}}}
+
+sub safequote ($) { #{{{
+       my $s=shift;
+       $s=~s/[{}]//g;
+       return "q{$s}";
+} #}}}
+
+sub pagespec_merge ($$) { #{{{
+       my $a=shift;
+       my $b=shift;
+
+        # Support for old-style GlobLists.
+        if (is_globlist($a)) {
+                $a=globlist_to_pagespec($a);
+        }
+        if (is_globlist($b)) {
+                $b=globlist_to_pagespec($b);
+        }
+
+       return "($a) or ($b)";
+} #}}}
+
+sub pagespec_match ($$) { #{{{
+       my $page=shift;
+       my $spec=shift;
+
+       # Support for old-style GlobLists.
+       if (is_globlist($spec)) {
+               $spec=globlist_to_pagespec($spec);
+       }
+
+       # Convert spec to perl code.
+       my $code="";
+       while ($spec=~m/\s*(\!|\(|\)|\w+\([^\)]+\)|[^\s()]+)\s*/ig) {
+               my $word=$1;
+               if (lc $word eq "and") {
+                       $code.=" &&";
+               }
+               elsif (lc $word eq "or") {
+                       $code.=" ||";
+               }
+               elsif ($word eq "(" || $word eq ")" || $word eq "!") {
+                       $code.=" ".$word;
+               }
+               elsif ($word =~ /^(link|backlink|creation_month|creation_year|creation_day)\((.+)\)$/) {
+                       $code.=" match_$1(\$page, ".safequote($2).")";
+               }
+               else {
+                       $code.=" match_glob(\$page, ".safequote($word).")";
+               }
+       }
+
+       return eval $code;
+} #}}}
+
+sub match_glob ($$) { #{{{
+       my $page=shift;
+       my $glob=shift;
+
+       # turn glob into safe regexp
+       $glob=quotemeta($glob);
+       $glob=~s/\\\*/.*/g;
+       $glob=~s/\\\?/./g;
+
+       return $page=~/^$glob$/;
+} #}}}
+
+sub match_link ($$) { #{{{
+       my $page=shift;
+       my $link=shift;
+
+       my $links = $links{$page} or return undef;
+       foreach my $p (@$links) {
+               return 1 if lc $p eq $link;
+       }
+       return 0;
+} #}}}
+
+sub match_backlink ($$) { #{{{
+       my $page=shift;
+       my $linkto=shift;
+
+       my $links = $links{$linkto} or return undef;
+       foreach my $p (@$links) {
+               return 1 if lc $p eq $page;
+       }
+       return 0;
+} #}}}
+
+sub match_creation_day ($$) { #{{{
+       return if (localtime($pagectime{shift()}))[3] == shift;
+} #}}}
+
+sub match_creation_month ($$) { #{{{
+       return if (localtime($pagectime{shift()}))[4] + 1 == shift;
+} #}}}
+
+sub match_creation_year ($$) { #{{{
+       return if (localtime($pagectime{shift()}))[5] + 1900 == shift;
+} #}}}
+
+
 1
index fc5dfc2efde84d552940dda35efc511ce92e87dd..f69f02a15af2396d51c3e116ada1cb8be3652d22 100644 (file)
@@ -31,7 +31,7 @@ sub page_locked ($$;$) { #{{{
 
        foreach my $admin (@{$config{adminuser}}) {
                my $locked_pages=userinfo_get($admin, "locked_pages");
-               if (globlist_match($page, userinfo_get($admin, "locked_pages"))) {
+               if (pagespec_match($page, userinfo_get($admin, "locked_pages"))) {
                        return 1 if $nonfatal;
                        error(htmllink("", "", $page, 1)." is locked by ".
                              htmllink("", "", $admin, 1)." and cannot be edited.");
@@ -278,9 +278,9 @@ sub cgi_prefs ($$) { #{{{
        $form->field(name => "password", type => "password");
        $form->field(name => "confirm_password", type => "password");
        $form->field(name => "subscriptions", size => 50,
-               comment => "(".htmllink("", "", "GlobList", 1).")");
+               comment => "(".htmllink("", "", "PageSpec", 1).")");
        $form->field(name => "locked_pages", size => 50,
-               comment => "(".htmllink("", "", "GlobList", 1).")");
+               comment => "(".htmllink("", "", "PageSpec", 1).")");
        
        if (! is_admin($user_name)) {
                $form->field(name => "locked_pages", type => "hidden");
index 7142e61063e731aaeee6b89f8d94e772c4e588c3..46f2d51285dfbf03408c476c07d5b69ca8db2fc8 100644 (file)
@@ -108,8 +108,6 @@ sub delete (@) { #{{{
 } #}}}
 
 sub loadstate () { #{{{
-       eval q{use HTML::Entities};
-       die $@ if $@;
        if (-e "$IkiWiki::config{wikistatedir}/aggregate") {
                open (IN, "$IkiWiki::config{wikistatedir}/aggregate" ||
                        die "$IkiWiki::config{wikistatedir}/aggregate: $!");
index 09ce181cff2a11f6e568e875baf95522cd211366..7fae9a2f2e5ceae2b5f11191bf83f6c835beee0a 100644 (file)
@@ -21,7 +21,7 @@ sub preprocess (@) { #{{{
        
        my @broken;
        foreach my $page (keys %IkiWiki::links) {
-               if (IkiWiki::globlist_match($page, $params{pages})) {
+               if (IkiWiki::pagespec_match($page, $params{pages})) {
                        foreach my $link (@{$IkiWiki::links{$page}}) {
                                next if $link =~ /.*\/discussion/i && $IkiWiki::config{discussion};
                                my $bestlink=IkiWiki::bestlink($page, $link);
index 6a0f00f0fd7a39b760d70e003b12eabad0d5ca6a..d8f2ca0d8baf6b70dc1d560d20a977b7a719993a 100644 (file)
@@ -48,7 +48,7 @@ sub preprocess_inline (@) { #{{{
        my @list;
        foreach my $page (keys %pagesources) {
                next if $page eq $params{page};
-               if (globlist_match($page, $params{pages})) {
+               if (pagespec_match($page, $params{pages})) {
                        push @list, $page;
                }
        }
index ac4b775273c6c9a0624ec79b6113c70551779837..2219634caa3a4c28d2a07276712847be48f8363b 100644 (file)
@@ -28,7 +28,7 @@ sub preprocess (@) { #{{{
        my @orphans;
        foreach my $page (keys %IkiWiki::renderedfiles) {
                next if $linkedto{$page};
-               next unless IkiWiki::globlist_match($page, $params{pages});
+               next unless IkiWiki::pagespec_match($page, $params{pages});
                # 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 { 
index 8a1376e09a022fb7be70ab3421a07693613dfa83..cfc962b6c4df0172fca409033326b3153602fc3f 100644 (file)
@@ -23,7 +23,7 @@ sub preprocess (@) { #{{{
        return $#pages+1 if $params{pages} eq "*"; # optimisation
        my $count=0;
        foreach my $page (@pages) {
-               $count++ if IkiWiki::globlist_match($page, $params{pages});
+               $count++ if IkiWiki::pagespec_match($page, $params{pages});
        }
        return $count;
 } # }}}
index a1b4c1d45b59ed7df414765012ddaead887a1030..de559e2c5a63c762eb3277a85efffb950c912793 100644 (file)
@@ -34,7 +34,7 @@ sub preprocess (@) { #{{{
        my %counts;
        my $max = 0;
        foreach my $page (keys %IkiWiki::links) {
-               if (IkiWiki::globlist_match($page, $params{pages})) {
+               if (IkiWiki::pagespec_match($page, $params{pages})) {
                        my @bl = IkiWiki::backlinks($page);
                        $counts{$page} = scalar(@bl);
                        $max = $counts{$page} if $counts{$page} > $max;
index 1449b8931cc9ebf364d0daf7841f1d7577c358b6..7cb55f12873c4e76ccaccf25e20953587346bd5f 100644 (file)
@@ -129,37 +129,16 @@ sub preprocess ($$$;$) { #{{{
 
 sub add_depends ($$) { #{{{
        my $page=shift;
-       my $globlist=shift;
+       my $pagespec=shift;
        
        if (! exists $depends{$page}) {
-               $depends{$page}=$globlist;
+               $depends{$page}=$pagespec;
        }
        else {
-               $depends{$page}=globlist_merge($depends{$page}, $globlist);
+               $depends{$page}=pagespec_merge($depends{$page}, $pagespec);
        }
 } # }}}
 
-sub globlist_merge ($$) { #{{{
-       my $a=shift;
-       my $b=shift;
-
-       my $ret="";
-       # Only add negated globs if they are not matched by the other globlist.
-       foreach my $i ((map { [ $a, $_ ] } split(" ", $b)), 
-                      (map { [ $b, $_ ] } split(" ", $a))) {
-               if ($i->[1]=~/^!(.*)/) {
-                       if (! globlist_match($1, $i->[0])) {
-                               $ret.=" ".$i->[1];
-                       }
-               }
-               else {
-                       $ret.=" ".$i->[1];
-               }
-       }
-       
-       return $ret;
-} #}}}
-
 sub genpage ($$$) { #{{{
        my $page=shift;
        my $content=shift;
@@ -441,7 +420,7 @@ FILE:               foreach my $file (@files) {
                                foreach my $file (keys %rendered, @del) {
                                        next if $f eq $file;
                                        my $page=pagename($file);
-                                       if (globlist_match($page, $depends{$p})) {
+                                       if (pagespec_match($page, $depends{$p})) {
                                                debug("rendering $f, which depends on $page");
                                                render($f);
                                                $rendered{$f}=1;
index fabe495bbe532821f507d6bdaf9342c70fb9ed3c..a944cafa6791e84a1ec9fb35a39761776dceda91 100644 (file)
@@ -83,7 +83,7 @@ sub commit_notify_list ($@) { #{{{
                    length $userinfo->{$user}->{subscriptions} &&
                    exists $userinfo->{$user}->{email} &&
                    length $userinfo->{$user}->{email} &&
-                   grep { globlist_match($_, $userinfo->{$user}->{subscriptions}) } @pages) {
+                   grep { pagespec_match($_, $userinfo->{$user}->{subscriptions}) } @pages) {
                        push @ret, $userinfo->{$user}->{email};
                }
        }
index 1993f372042cc0d93dbe221178dd50db1e8b3b13..4c8d7d40665548a6ce0d6df8eef7b71f5c54f0c5 100644 (file)
@@ -1,9 +1,9 @@
 You can turn any page on this wiki into a weblog by inserting a
 [[PreProcessorDirective]]. Like this:
 
-       \\[[inline pages="blog/* !*/Discussion" show="10" rootpage="blog"]]
+       \\[[inline pages="blog/* and !*/Discussion" show="10" rootpage="blog"]]
 
-Any pages that match the specified [[GlobList]] (in the example, any
+Any pages that match the specified [[PageSpec]] (in the example, any
 [[SubPage]] of "blog") will be part of the blog, and the newest 10
 of them will appear in the page.
 
@@ -18,20 +18,20 @@ globally configured to do so, but you can set `rss=no` to disable this.
 If you want your blog to have an archive page listing every post ever made
 to it, you can accomplish that like this:
 
-       \\[[inline pages="blog/* !*/Discussion" archive="yes"]]
+       \\[[inline pages="blog/* and !*/Discussion" archive="yes"]]
 
 You can even create an automatically generated list of all the pages on the
 wiki, with the most recently added at the top, like this:
 
-       \\[[inline pages="* !*/Discussion" archive="yes"]]
+       \\[[inline pages="* and !*/Discussion" archive="yes"]]
 
 If you want to be able to add pages to a given blog feed by tagging them,
 you can do that too. To tag a page, just make it link to a page or pages 
-that represent its tags. Then use the special link() [[GlobList]] to match
+that represent its tags. Then use the special link() [[PageSpec]] to match
 all pages that have a given tag:
 
        \\[[inline pages="link(life)"]]
 
 Or include some tags and exclude others:
 
-       \\[[inline pages="link(debian) !link(social)"]]
+       \\[[inline pages="link(debian) and !link(social)"]]
diff --git a/basewiki/globlist.mdwn b/basewiki/globlist.mdwn
deleted file mode 100644 (file)
index 20a9eed..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-When the wiki stores lists of pages, such as pages that are locked or pages
-whose commit emails you want subscribe to, it uses a GlobList.
-
-This is a list of page names, separated by white space. The "glob" bit is
-that as well as full page names, it can contain glob patterns. "`*`" stands
-in for any part of the page name, and "`?`" for any single letter of its
-name. So if you wanted to list all the pages about tea, and any
-[[SubPage]]s of the SandBox, but not including the SandBox itself:
-
-       *tea* SandBox/*
-
-You can also prefix an item in the list with "`!`" to skip matching any
-pages that match it. So if you want to specify all pages except for
-Discussion pages and the SandBox:
-
-       * !SandBox !*/Discussion
-
-It's also possible to match pages that link to a given page, by writing
-"link(page)" in a globlist. Or, match pages that a given page links to, by
-writing "backlink(page)".
diff --git a/basewiki/pagespec.mdwn b/basewiki/pagespec.mdwn
new file mode 100644 (file)
index 0000000..318be42
--- /dev/null
@@ -0,0 +1,61 @@
+To select a set of pages, such as pages that are locked, pages
+whose commit emails you want subscribe to, or pages to combine into a
+[[blog]], the wiki uses a PageSpec. This is an expression that matches
+a set of pages.
+
+The simplest PageSpec is a simple list of pages. For example, this matches
+any of the three listed pages:
+
+       foo or bar or baz
+
+More often you will want to match any pages that have a particular thing in
+their name. You can do this using a glob pattern. "`*`" stands for any part
+of a page name, and "`?`" for any single letter of a page name. So this
+matches all pages about music, and any [[SubPage]]s of the SandBox, but does
+not match the SandBox itself:
+
+       *music* or SandBox/*
+
+You can also prefix an item with "`!`" to skip pages that match it. So to
+match all pages except for Discussion pages and the SandBox:
+
+       * and !SandBox and !*/Discussion
+
+It's also possible to match pages that link to a given page, by writing
+"`link(page)`". Or, match pages that a given page links to, by
+writing "`backlink(page)`". Or match pages created in a given month, year,
+or day of the month by writing "`creation_month(month)`",
+"`creation_year(year)`" or "`creation_day(mday)`".
+
+For example, to match all pages in a blog that link to the page about music
+and were written on Mondays in 2005:
+
+       blog/* and link(music) and creation_year(2005) and creation_day(0)
+
+Matches can also be used to limit matching to pages created before or after
+a given date. 
+
+More complex expressions can also be created, by using parentheses for
+grouping. For example, to match pages in a blog that are tagged with either
+of two tags, use:
+
+       blog/* and (link(tag/foo) or link(tag/bar))
+
+## Old syntax
+
+The old PageSpec syntax was called a "GlobList", and worked differently in
+two ways:
+
+1. "and" and "or" were not used; any page matching any item from the list
+   matched.
+2. If an item was prefixed with "`!`", then no page matching that item
+   matched, even if it matched an earlier list item.
+
+For example, here is the old way to match all pages except for the SandBox
+and Discussion pages:
+
+       * !SandBox !*/Discussion
+
+Using this old syntax is still supported. However, the old syntax is
+deprecated and will be removed at some point, and using the new syntax is
+recommended.
index 1c087d2dc6d48e51d654926809015b54d5ab7339..4393a4cbba7867218ab728b25c8e9724c2313a20 100644 (file)
@@ -1,3 +1,19 @@
+ikiwiki (1.13) unstable; urgency=low
+
+  The GlobList format which was used for specifiying sets of pages, has been
+  replaced with a new PageSpec format. While GlobLists will continue to work,
+  that format is deprecated, and you are recommended to use PageSpecs from now
+  on, and also to change any GlobLists in your wiki to PageSpecs. 
+  
+  See the new PageSpec page for details.
+  
+  You will need to rebuild your wiki when upgrading to this version. If you
+  listed your wiki in /etc/ikiwiki/wikilist this will be done automatically
+  when the Debian package is upgraded. Or use ikiiki-mass-rebuild to force a
+  rebuild.
+
+ -- Joey Hess <joeyh@debian.org>  Tue,  1 Aug 2006 18:29:51 -0400
+
 ikiwiki (1.11) unstable; urgency=low
 
   Some changes to tags in this release, due to a new tag plugin. If you have
index 9e183576bb6106453421125e28c177dd29ab32be..befe1dda44f2a6e5c3cc7214f0e4b71f85bd96bc 100644 (file)
@@ -24,6 +24,18 @@ ikiwiki (1.13) UNRELEASED; urgency=low
     index. (Aka Please Please Please, let that be the last one.)
   * Patch from Roland Mas to support an rss=no parameter to inline directives.
     Closes: #380743
+  * Renamed GlobLists to PageSpecs.
+  * PageSpecs can now include nested parens, "and", and "or". This remains
+    backwards compatible to the old GlobList format. It's implemented by
+    treating the GlobList as a very limited microlanguage that is transformed
+    to perl code that does the matching.
+  * The old GlobList format is deprecated, and I encourage users to switch to
+    using the new PageSpec format. Compatability with the old format will be
+    removed at some point, possibly by 2.0.
+  * Wiki rebuild needed on upgrade to this version due to PageSpec change.
+  * Add support for creation_month and creation_year to PageSpec.
+    Closes: #380680
+  * Changes to index file encoding.
 
  -- Joey Hess <joeyh@debian.org>  Tue,  1 Aug 2006 16:00:58 -0400
 
index 4e2425fcb07196e91c025c0b14b3412b9e874335..b3031bd9b944a80f0d61f38b74b949f8f2a6bcf0 100755 (executable)
@@ -4,7 +4,7 @@ set -e
 
 # Change this when some incompatible change is made that requires
 # rebuilding all wikis.
-firstcompat=1.4
+firstcompat=1.13
 
 if [ "$1" = configure ] && \
    dpkg --compare-versions "$2" lt "$firstcompat"; then
index c4895cb7b1b129333cfb9d23d22c6eca0f00133a..2046fb820839039bfa05991512ebbdf4885121e2 100644 (file)
@@ -1,9 +1,9 @@
 This is ikiwiki's bug list. Link bugs to [[bugs/done]] when done.
 
-[[inline pages="bugs/* !bugs/done !link(bugs/done) !*/Discussion" rootpage="bugs" show="30"]]
+[[inline pages="bugs/* and !bugs/done and !link(bugs/done) and !*/Discussion" rootpage="bugs" show="30"]]
 
 ----
 
 # Full list of open bugs:
 
-[[inline pages="bugs/* !bugs/done !link(bugs/done) !*/Discussion" archive="yes" rss="no"]]
+[[inline pages="bugs/* and !bugs/done and !link(bugs/done) and !*/Discussion" archive="yes" rss="no"]]
index 58c4719b76082bd84f3d0f9314cda19f7c7248dc..a92862bd4de981da369db9eb746c5364e2e345cd 100644 (file)
@@ -1,3 +1,3 @@
 recently fixed [[bugs]]
 
-[[inline pages="link(bugs/done) !bugs !*/Discussion" show="10"]]
+[[inline pages="link(bugs/done) and !bugs and !*/Discussion" show="10"]]
index 35fe5e1895b36cea301a1fb86d24af41f7fde06b..69dc6fb8d24f54b888009bb18052cebb182311e9 100644 (file)
@@ -2,16 +2,16 @@ If a page inlines some other page (such as this page by the bugs page),
 and the page is removed (such as by this page being linked to bugs/done),
 the inlining page is not updated to remove it.
 
-This only happens if the page is removed from the inlined globlist due to
+This only happens if the page is removed from the inlined pagespec due to
 a tag changing; the problem is that once the tag is changed, ikiwiki does
 not know that the page used to match before.
 
 To fix, seems I would need to record the actual list of pages that are
 currently included on an inline page, and do a comparison to see if any
 have changed. At first I thought, why not just add them to the dependencies
-explicitly, but that fails because the dependencies globlist fails to match
+explicitly, but that fails because the dependencies pagespec fails to match
 when a negated expression like "!tag(bugs/done)" is matched.
 
 So, quick fixes aside, what's the generic mechanism here that a plugin can
 use to let ikiwiki know that a page should be updated if some other page
-stops matching its dependencies globlist?
+stops matching its dependencies pagespec?
index 0a235d7083557702ef822702485730cf3e541ad6..27db7bc65546c2ad4be8856d95b6c44f97e7ab7b 100644 (file)
@@ -46,7 +46,7 @@ Some of ikiwiki's features:
 * [[blogging|blog]]
 
   You can turn any page in the wiki into a [[blog]]. Pages matching a
-  specified [[GlobList]] will be displayed as a weblog within the blog
+  specified [[PageSpec]] will be displayed as a weblog within the blog
   page. And an RSS feed can be generated to follow the blog.
 
   Ikiwiki's own [[TODO]], [[news]], and [[plugins]] pages are good examples
index eb5b91e678532fb33f196d790968c55a7b3b3bae..d2b6b8833fd61720bc8f24a7202685032a88895b 100644 (file)
@@ -1,10 +1,10 @@
 The easiest way to install ikiwiki is using the Debian package.
 
-Ikiwiki requires [[MarkDown]] be installed, and also uses the following
-perl modules if available: `CGI::Session` `CGI::FormBuilder` (version
-3.02.02 or newer) `HTML::Template` `Mail::SendMail` `Time::Duration`
-`Date::Parse` (libtimedate-perl), `HTML::Scrubber`, `RPC::XML`,
-`XML::Simple`, `XML::Feed`, `HTML::Parser`
+Ikiwiki requires [[MarkDown]] and the `HTML::Parser` perl module be
+installed, and also uses the following perl modules if available: 
+`CGI::Session` `CGI::FormBuilder` (version 3.02.02 or newer)
+`HTML::Template` `Mail::SendMail` `Time::Duration` `Date::Parse`,
+`HTML::Scrubber`, `RPC::XML`, `XML::Simple`, `XML::Feed`
 
 If you want to install from the tarball, you should make sure that the
 required perl modules are installed, then run:
index 816fc74d3d4511d1aeb519eaeaa39a85ba78ac6c..781666c2ad892ef2c0acc7ba5afde88a0a148a15 100644 (file)
@@ -2,7 +2,7 @@ This is where annoucements of new releases, features, and other news is
 posted. [[IkiWikiUsers]] are recommended to subscribe to this page's RSS
 feed.
 
-[[inline pages="news/* !*/Discussion" rootpage="news" show="30"]]
+[[inline pages="news/* and !*/Discussion" rootpage="news" show="30"]]
 
 By the way, some other pages with RSS feeds about ikiwiki include
 [[plugins]], [[TODO]] and [[bugs]].
index 29631fe9dc1a1cda9ad1706deeb5a5e1d1c40905..91dc224a7b29513501db39f89b98bc2b734a2da5 100644 (file)
@@ -5,5 +5,4 @@ Feel free to either copy the patch inline, or link to one elsewhere (or nag
 Joey to open up anonymous svn access to this wiki so you can check in the
 patches directly).
 
-[[inline pages="patchqueue/* !patchqueue/done !link(patchqueue/done) !*/Discussion" rootpage="patchqueue" show="30" archive="yes"]]
-
+[[inline pages="patchqueue/* and !patchqueue/done and !link(patchqueue/done) and !*/Discussion" rootpage="patchqueue" show="30" archive="yes"]]
index 3c23c9d6897b31ce433ffa55983a12eaa5e51a20..e3f6357b789444442b233de478fceea042914d9d 100644 (file)
@@ -2,7 +2,7 @@ This plugin generates a list of broken links on pages in the wiki. This is
 a useful way to find pages that still need to be written, or links that
 are written wrong.
 
-The optional parameter "pages" can be a [[GlobList]] specifying the pages
+The optional parameter "pages" can be a [[PageSpec]] specifying the pages
 to search for broken links, default is search them all.
 
 This plugin is included in ikiwiki, but is not enabled by default.
index 0c2ea69da42c1271e4ef3c241a53147dc678ad28..2c4e52a3ff22845fa35fcc357d3532606db3c9ea 100644 (file)
@@ -1,7 +1,7 @@
 This plugin generates a list of possibly orphaned pages -- pages that no other page
 links to.
 
-The optional parameter "pages" can be a [[GlobList]] specifying the pages
+The optional parameter "pages" can be a [[PageSpec]] specifying the pages
 to check for orphans, default is search them all.
 
 Note that it takes [[BackLinks]] into account, but does not count inlining a
index 0fddecf305872a98e02530412b403cd96932b5de..8fc04ff762c6061e98f856d002ba0d775dd2cb75 100644 (file)
@@ -1,7 +1,7 @@
 Provides a \\[[pagecount ]] [[PreProcessorDirective]] that is replaced with
 the total number of pages currently in the wiki.
 
-The optional parameter "pages" can be a [[GlobList]] specifying the pages
+The optional parameter "pages" can be a [[PageSpec]] specifying the pages
 to count, default is to count them all.
 
 This plugin is included in ikiwiki, but is not enabled by default.
index ed5336ad59ead09cb277dccb858dbf345d8ac52e..94a6280ca63bb7c33dee21bd5053dee0c480709f 100644 (file)
@@ -3,7 +3,7 @@ This plugin allows tagging pages. List tags as follows:
        \[[tag tech life linux]]
 
 The tags work the same as if you had put a (hidden) [[WikiLink]] on the page
-for each tag, so you can use a [[GlobList]] to link to all pages that are
+for each tag, so you can use a [[PageSpec]] to link to all pages that are
 tagged with a given tag, for example. The tags will also show up on blog
 entries and at the bottom of the tagged pages, as well as in rss feeds.
 
index 925717777d93360639ba3a7402dadb5944db95a5..79bd75e9b8583d0e5fa13769b22f3a7b924cd979 100644 (file)
@@ -183,13 +183,13 @@ use the following hashes, using a page name as the key:
 * `%IkiWiki::renderedfiles` contains the name of the file rendered by a
   page
 * `%IkiWiki::pagesources` contains the name of the source file for a page.
-* `%IkiWiki::depends` contains a [[GlobList]] that is used to specify other
+* `%IkiWiki::depends` contains a [[PageSpec]] that is used to specify other
   pages that a page depends on. If one of its dependencies is updated, the
   page will also get rebuilt. 
   
   Many plugins will need to add dependencies to this hash; the best way to do
   it is by using the IkiWiki::add_depends function, which takes as its
-  parameters the page name and a [[GlobList]] of dependencies to add.
+  parameters the page name and a [[PageSpec]] of dependencies to add.
 * `%IkiWiki::forcerebuild` any pages set as the keys to this hash will be
   treated as if they're modified and rebuilt.
 
index 05ee48dff272cf801a31074aff46a6348dae3f1f..672dfe3c4c36fbd188b27519206eeb5e634297a2 100644 (file)
@@ -13,7 +13,7 @@ Released 29 April 2006.
 # 2.0
 
 * Unit test suite (with tests of at least core stuff like
-  [[GlobList]]). (status: exists, could of course use more tests)
+  [[PageSpec]]). (status: exists, could of course use more tests)
 * [[Plugins]] _(status: done, interface still not quite stable)_
 * [[Tags]] _(status: partial)_
 * Should have fully working [[todo/utf8]] support. _(status: fair)_
index b89d2cdf061cfc885a138568ed16ddf3a993eb64..9a0a593bebe64425967e3e0f2677403e9e421814 100644 (file)
@@ -1,9 +1,9 @@
 Welcome to ikiwiki's todo list. Link items to [[todo/done]] when done.
 
-[[inline pages="todo/* !todo/done !link(todo/done) !*/Discussion" rootpage="todo" show="30"]]
+[[inline pages="todo/* and !todo/done and !link(todo/done) and !*/Discussion" rootpage="todo" show="30"]]
 
 ----
 
 # Full list of open items:
 
-[[inline pages="todo/* !todo/done !link(todo/done) !*/Discussion" archive="yes" rss="no"]]
+[[inline pages="todo/* and !todo/done and !link(todo/done) and !*/Discussion" archive="yes" rss="no"]]
index 847d0a2e5a8548a313cab9a446ec03f0120ac192..8d01666c0ec468b7f32fcd55574e19dc9e6fe9ab 100644 (file)
@@ -1,3 +1,3 @@
 recently fixed [[TODO]] items
 
-[[inline pages="link(todo/done) !todo !*/Discussion" show="10"]]
+[[inline pages="link(todo/done) and !todo and !*/Discussion" show="10"]]
index 80b545e4e154ed4cb9c7e5201a00bb747d556a70..86a4ba154a2d629d22ff28d2a6c5c04a1e8e786f 100644 (file)
@@ -1,6 +1,8 @@
-Need to improve [[globlist]]s, adding more powerful boolean expressions.
+Need to improve globlists, adding more powerful boolean expressions.
 The current behavior is to check for negated expressions, and not match if
 there are any, then check for normal expressions and match if any match,
 This fails if you want to do something like match only pages with tag foo
 that are under directory bar. I think we need parens for grouping, and
 probably also boolean OR.
+
+[[todo/done]]
index 459a5fa4ff1ebdcebde0106169c9ed6e1c06990f..258d584dd8ad2d27e2b260d630ea5a36b4e0baf9 100644 (file)
@@ -2,7 +2,7 @@
 > file for some pages; blog pages would use a template different from the
 > home page, even if both are managed in the same repository, etc.
 
-Well, that would probably be fairly easy to add if it used globlists to
+Well, that would probably be fairly easy to add if it used pagespecs to
 specify which pages use the non-default template.
 
 Hmm, I think the pagetemplate hook should allow one to get close enough to
diff --git a/t/globlist_match.t b/t/globlist_match.t
deleted file mode 100755 (executable)
index b60d83a..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/perl
-use warnings;
-use strict;
-use Test::More tests => 13;
-
-BEGIN { use_ok("IkiWiki"); }
-ok(IkiWiki::globlist_match("foo", "foo bar"), "simple list");
-ok(IkiWiki::globlist_match("bar", "foo bar"), "simple list 2");
-ok(IkiWiki::globlist_match("foo", "*"));
-ok(IkiWiki::globlist_match("foo", "f?? !foz"));
-ok(! IkiWiki::globlist_match("foo", "f?? !foo"));
-ok(! IkiWiki::globlist_match("foo", "* !foo"));
-ok(! IkiWiki::globlist_match("foo", "foo !foo"));
-ok(IkiWiki::globlist_match("page", "?ag?"));
-ok(! IkiWiki::globlist_match("page", "?a?g?"));
-ok(! IkiWiki::globlist_match("foo.png", "* !*.*"));
-ok(IkiWiki::globlist_match("foo.png", "*.*"));
-ok(! IkiWiki::globlist_match("foo", "*.*"));
diff --git a/t/pagespec_match.t b/t/pagespec_match.t
new file mode 100755 (executable)
index 0000000..35d420f
--- /dev/null
@@ -0,0 +1,28 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+use Test::More tests => 20;
+
+BEGIN { use_ok("IkiWiki"); }
+
+ok(IkiWiki::pagespec_match("foo", "*"));
+ok(IkiWiki::pagespec_match("page", "?ag?"));
+ok(! IkiWiki::pagespec_match("page", "?a?g?"));
+ok(IkiWiki::pagespec_match("foo.png", "*.*"));
+ok(! IkiWiki::pagespec_match("foo", "*.*"));
+ok(IkiWiki::pagespec_match("foo", "foo or bar"), "simple list");
+ok(IkiWiki::pagespec_match("bar", "foo or bar"), "simple list 2");
+ok(IkiWiki::pagespec_match("foo", "f?? and !foz"));
+ok(! IkiWiki::pagespec_match("foo", "f?? and !foo"));
+ok(! IkiWiki::pagespec_match("foo", "* and !foo"));
+ok(! IkiWiki::pagespec_match("foo", "foo and !foo"));
+ok(! IkiWiki::pagespec_match("foo.png", "* and !*.*"));
+
+# old style globlists
+ok(IkiWiki::pagespec_match("foo", "foo bar"), "simple list");
+ok(IkiWiki::pagespec_match("bar", "foo bar"), "simple list 2");
+ok(IkiWiki::pagespec_match("foo", "f?? !foz"));
+ok(! IkiWiki::pagespec_match("foo", "f?? !foo"));
+ok(! IkiWiki::pagespec_match("foo", "* !foo"));
+ok(! IkiWiki::pagespec_match("foo", "foo !foo"));
+ok(! IkiWiki::pagespec_match("foo.png", "* !*.*"));
similarity index 86%
rename from t/globlist_merge.t
rename to t/pagespec_merge.t
index db76f1cd44229ed20deecfd461c8d15919279db2..c2860709b3f44b32940504ccf7670f392e53b4aa 100755 (executable)
@@ -8,14 +8,14 @@ sub same {
        my $b=shift;
        my $match=shift;
        
-       my $imatch=(IkiWiki::globlist_match($match, $a) ||
-                   IkiWiki::globlist_match($match, $b));
-       my $cmatch=IkiWiki::globlist_match($match, IkiWiki::globlist_merge($a, $b));
+       my $imatch=(IkiWiki::pagespec_match($match, $a) ||
+                   IkiWiki::pagespec_match($match, $b));
+       my $cmatch=IkiWiki::pagespec_match($match, IkiWiki::pagespec_merge($a, $b));
        
        return $imatch == $cmatch;
 }
 
-BEGIN { use_ok("IkiWiki::Render"); }
+BEGIN { use_ok("IkiWiki"); }
 
 ok(same("foo", "bar", "foo"), "basic match 1");
 ok(same("foo", "bar", "bar"), "basic match 2");
@@ -36,8 +36,8 @@ ok(same("f?? !f??", "!bar", "bar"), "matching glob and matching inverted glob");
 ok(same("b??", "!b?z", "bar"), "matching glob and non-matching inverted glob");
 ok(same("f?? !f?z", "!bar", "bar"), "matching glob and non-matching inverted glob");
 ok(same("!foo bar baz", "!bar", "bar"), "matching list and matching inversion");
-ok(IkiWiki::globlist_match("foo/Discussion",
-       IkiWiki::globlist_merge("* !*/Discussion", "*/Discussion")), "should match");
+ok(IkiWiki::pagespec_match("foo/Discussion",
+       IkiWiki::pagespec_merge("* !*/Discussion", "*/Discussion")), "should match");
 ok(same("* !*/Discussion", "*/Discussion", "foo/Discussion"), "Discussion merge 1");
 ok(same("*/Discussion", "* !*/Discussion", "foo/Discussion"), "Discussion merge 2");
 ok(same("*/Discussion !*/bar", "*/bar !*/Discussion", "foo/Discussion"), "bidirectional merge 1");