Merge branch 'master' of git://github.com/joeyh/ikiwiki
authorAmitai Schlair <schmonz@magnetic-babysitter.(none)>
Sun, 30 Aug 2009 07:02:15 +0000 (03:02 -0400)
committerAmitai Schlair <schmonz@magnetic-babysitter.(none)>
Sun, 30 Aug 2009 07:02:15 +0000 (03:02 -0400)
1  2 
IkiWiki.pm
IkiWiki/Render.pm

diff --combined IkiWiki.pm
index 2355c07807cbbd6c854002764c1b2e499208ed3e,b8e89b73fb00db7df6d019d07895376b0932cd8f..453bc9f8ca0898b97c2242d36367ec2ecb077b13
@@@ -13,8 -13,8 +13,8 @@@ use open qw{:utf8 :std}
  
  use vars qw{%config %links %oldlinks %pagemtime %pagectime %pagecase
            %pagestate %wikistate %renderedfiles %oldrenderedfiles
-           %pagesources %destsources %depends %hooks %forcerebuild
-           %loaded_plugins};
+           %pagesources %destsources %depends %depends_simple %hooks
+           %forcerebuild %loaded_plugins};
  
  use Exporter q{import};
  our @EXPORT = qw(hook debug error template htmlpage add_depends pagespec_match
@@@ -220,6 -220,13 +220,13 @@@ sub getsetup () 
                safe => 1,
                rebuild => 1,
        },
+       discussionpage => {
+               type => "string",
+               default => gettext("Discussion"),
+               description => "name of Discussion pages",
+               safe => 1,
+               rebuild => 1,
+       },
        sslcookie => {
                type => "boolean",
                default => 0,
                        qr/\.x?html?$/, qr/\.ikiwiki-new$/,
                        qr/(^|\/).svn\//, qr/.arch-ids\//, qr/{arch}\//,
                        qr/(^|\/)_MTN\//, qr/(^|\/)_darcs\//,
 -                      qr/\.dpkg-tmp$/],
 +                      qr/(^|\/)CVS\//, qr/\.dpkg-tmp$/],
                description => "regexps of source files to ignore",
                safe => 0,
                rebuild => 1,
@@@ -654,9 -661,15 +661,15 @@@ sub pagetype ($) 
        return;
  }
  
+ my %pagename_cache;
  sub pagename ($) {
        my $file=shift;
  
+       if (exists $pagename_cache{$file}) {
+               return $pagename_cache{$file};
+       }
        my $type=pagetype($file);
        my $page=$file;
        $page=~s/\Q.$type\E*$//
        if ($config{indexpages} && $page=~/(.*)\/index$/) {
                $page=$1;
        }
+       $pagename_cache{$file} = $page;
        return $page;
  }
  
@@@ -1248,9 -1263,10 +1263,10 @@@ sub preprocess ($$$;$$) 
                                        );
                                };
                                if ($@) {
-                                       chomp $@;
+                                       my $error=$@;
+                                       chomp $error;
                                        $ret="[[!$command <span class=\"error\">".
-                                               gettext("Error").": $@"."</span>]]";
+                                               gettext("Error").": $error"."</span>]]";
                                }
                        }
                        else {
@@@ -1459,7 -1475,8 +1475,8 @@@ sub loadindex () 
        %oldrenderedfiles=%pagectime=();
        if (! $config{rebuild}) {
                %pagesources=%pagemtime=%oldlinks=%links=%depends=
-               %destsources=%renderedfiles=%pagecase=%pagestate=();
+               %destsources=%renderedfiles=%pagecase=%pagestate=
+               %depends_simple=();
        }
        my $in;
        if (! open ($in, "<", "$config{wikistatedir}/indexdb")) {
                                $links{$page}=$d->{links};
                                $oldlinks{$page}=[@{$d->{links}}];
                        }
-                       if (exists $d->{depends}) {
-                               $depends{$page}=$d->{depends};
+                       if (exists $d->{depends_simple}) {
+                               $depends_simple{$page}={
+                                       map { $_ => 1 } @{$d->{depends_simple}}
+                               };
+                       }
+                       if (exists $d->{dependslist}) {
+                               $depends{$page}={
+                                       map { $_ => 1 } @{$d->{dependslist}}
+                               };
+                       }
+                       elsif (exists $d->{depends}) {
+                               $depends{$page}={$d->{depends} => 1};
                        }
                        if (exists $d->{state}) {
                                $pagestate{$page}=$d->{state};
@@@ -1546,7 -1573,11 +1573,11 @@@ sub saveindex () 
                };
  
                if (exists $depends{$page}) {
-                       $index{page}{$src}{depends} = $depends{$page};
+                       $index{page}{$src}{dependslist} = [ keys %{$depends{$page}} ];
+               }
+               if (exists $depends_simple{$page}) {
+                       $index{page}{$src}{depends_simple} = [ keys %{$depends_simple{$page}} ];
                }
  
                if (exists $pagestate{$page}) {
@@@ -1716,16 -1747,17 +1747,17 @@@ sub rcs_receive () 
  sub add_depends ($$) {
        my $page=shift;
        my $pagespec=shift;
-       
-       return unless pagespec_valid($pagespec);
  
-       if (! exists $depends{$page}) {
-               $depends{$page}=$pagespec;
-       }
-       else {
-               $depends{$page}=pagespec_merge($depends{$page}, $pagespec);
+       if ($pagespec =~ /$config{wiki_file_regexp}/ &&
+               $pagespec !~ /[\s*?()!]/) {
+               # a simple dependency, which can be matched by string eq
+               $depends_simple{$page}{lc $pagespec} = 1;
+               return 1;
        }
  
+       return unless pagespec_valid($pagespec);
+       $depends{$page}{$pagespec} = 1;
        return 1;
  }
  
@@@ -1809,14 -1841,6 +1841,6 @@@ sub add_link ($$) 
                unless grep { $_ eq $link } @{$links{$page}};
  }
  
- sub pagespec_merge ($$) {
-       my $a=shift;
-       my $b=shift;
-       return $a if $a eq $b;
-       return "($a) or ($b)";
- }
  sub pagespec_translate ($) {
        my $spec=shift;
  
@@@ -2048,7 -2072,7 +2072,7 @@@ sub match_created_before ($$;@) 
                }
        }
        else {
-               return IkiWiki::FailReason->new("$testpage has no ctime");
+               return IkiWiki::ErrorReason->new("$testpage does not exist");
        }
  }
  
@@@ -2068,7 -2092,7 +2092,7 @@@ sub match_created_after ($$;@) 
                }
        }
        else {
-               return IkiWiki::FailReason->new("$testpage has no ctime");
+               return IkiWiki::ErrorReason->new("$testpage does not exist");
        }
  }
  
diff --combined IkiWiki/Render.pm
index 74033fa974165444359c811d4f2a1c90dd46a26d,246c2260d7748e9fe2b3522d73035564e0fb6754..5953b3feef93c9af06b8a491141635f3552fae82
@@@ -8,26 -8,31 +8,31 @@@ use IkiWiki
  use Encode;
  
  my %backlinks;
- my $backlinks_calculated=0;
+ our %brokenlinks;
+ my $links_calculated=0;
  
- sub calculate_backlinks () {
-       return if $backlinks_calculated;
-       %backlinks=();
+ sub calculate_links () {
+       return if $links_calculated;
+       %backlinks=%brokenlinks=();
        foreach my $page (keys %links) {
                foreach my $link (@{$links{$page}}) {
                        my $bestlink=bestlink($page, $link);
-                       if (length $bestlink && $bestlink ne $page) {
-                               $backlinks{$bestlink}{$page}=1;
+                       if (length $bestlink) {
+                               $backlinks{$bestlink}{$page}=1
+                                       if $bestlink ne $page;
+                       }
+                       else {
+                               push @{$brokenlinks{$link}}, $page;
                        }
                }
        }
-       $backlinks_calculated=1;
+       $links_calculated=1;
  }
  
  sub backlink_pages ($) {
        my $page=shift;
  
-       calculate_backlinks();
+       calculate_links();
  
        return keys %{$backlinks{$page}};
  }
@@@ -83,11 -88,10 +88,10 @@@ sub genpage ($$) 
                $actions++;
        }
        if ($config{discussion}) {
-               my $discussionlink=lc(gettext("Discussion"));
-               if ($page !~ /.*\/\Q$discussionlink\E$/ &&
+               if ($page !~ /.*\/\Q$config{discussionpage}\E$/ &&
                   (length $config{cgiurl} ||
-                   exists $links{$page."/".$discussionlink})) {
-                       $template->param(discussionlink => htmllink($page, $page, gettext("Discussion"), noimageinline => 1, forcesubpage => 1));
+                   exists $links{$page."/".$config{discussionpage}})) {
+                       $template->param(discussionlink => htmllink($page, $page, $config{discussionpage}, noimageinline => 1, forcesubpage => 1));
                        $actions++;
                }
        }
@@@ -153,7 -157,7 +157,7 @@@ sub scan ($) 
                if ($config{discussion}) {
                        # Discussion links are a special case since they're
                        # not in the text of the page, but on its template.
-                       $links{$page}=[ $page."/".lc(gettext("Discussion")) ];
+                       $links{$page}=[ $page."/".lc($config{discussionpage}) ];
                }
                else {
                        $links{$page}=[];
@@@ -206,6 -210,7 +210,7 @@@ sub render ($) 
        if (defined $type) {
                my $page=pagename($file);
                delete $depends{$page};
+               delete $depends_simple{$page};
                will_render($page, htmlpage($page), 1);
                return if $type=~/^_/;
                
        }
        else {
                delete $depends{$file};
+               delete $depends_simple{$file};
                will_render($file, $file, 1);
                
                if ($config{hardlink}) {
@@@ -417,7 -423,7 +423,7 @@@ sub refresh () 
                debug(sprintf(gettext("scanning %s"), $file));
                scan($file);
        }
-       calculate_backlinks();
+       calculate_links();
        foreach my $file (@needsbuild) {
                debug(sprintf(gettext("building %s"), $file));
                render($file);
                # internal pages are not rendered
                my $page=pagename($file);
                delete $depends{$page};
+               delete $depends_simple{$page};
                foreach my $old (@{$renderedfiles{$page}}) {
                        delete $destsources{$old};
                }
        if (%rendered || @del || @internal) {
                my @changed=(keys %rendered, @del);
  
+               my %lcchanged = map { lc(pagename($_)) => 1 } @changed;
+  
                # rebuild dependant pages
                foreach my $f (@$files) {
                        next if $rendered{$f};
                        my $p=pagename($f);
-                       if (exists $depends{$p}) {
-                               # only consider internal files
-                               # if the page explicitly depends on such files
-                               foreach my $file (@changed, $depends{$p}=~/internal\(/ ? @internal : ()) {
-                                       next if $f eq $file;
-                                       my $page=pagename($file);
-                                       if (pagespec_match($page, $depends{$p}, location => $p)) {
-                                               debug(sprintf(gettext("building %s, which depends on %s"), $f, $page));
-                                               render($f);
-                                               $rendered{$f}=1;
+                       my $reason = undef;
+                       if (exists $depends_simple{$p}) {
+                               foreach my $d (keys %{$depends_simple{$p}}) {
+                                       if (exists $lcchanged{$d}) {
+                                               $reason = $d;
                                                last;
                                        }
                                }
                        }
+                       if (exists $depends{$p} && ! defined $reason) {
+                               D: foreach my $d (keys %{$depends{$p}}) {
+                                       my $sub=pagespec_translate($d);
+                                       next if $@ || ! defined $sub;
+                                       # only consider internal files
+                                       # if the page explicitly depends
+                                       # on such files
+                                       foreach my $file (@changed, $d =~ /internal\(/ ? @internal : ()) {
+                                               next if $file eq $f;
+                                               my $page=pagename($file);
+                                               if ($sub->($page, location => $p)) {
+                                                       $reason = $page;
+                                                       last D;
+                                               }
+                                       }
+                               }
+                       }
+                       if (defined $reason) {
+                               debug(sprintf(gettext("building %s, which depends on %s"), $f, $reason));
+                               render($f);
+                               $rendered{$f}=1;
+                       }
                }
                
                # handle backlinks; if a page has added/removed links,
        if (%rendered) {
                run_hooks(change => sub { shift->(keys %rendered) });
        }
 +      run_hooks(postrefresh => sub { shift->() });
  }
  
  sub commandline_render () {