]> sipb.mit.edu Git - ikiwiki.git/blobdiff - IkiWiki/Render.pm
move decode_utf8 closer to reason for it
[ikiwiki.git] / IkiWiki / Render.pm
index 5b72b6de1665a26d319aa3ee2664ad05a409a45b..fff9dcce610e76be5c7ebf5e32bcd7b5c7ed7e69 100644 (file)
@@ -43,7 +43,7 @@ sub backlinks ($) {
        my @links;
        foreach my $p (backlink_pages($page)) {
                my $href=urlto($p, $page);
-                
+
                # Trim common dir prefixes from both pages.
                my $p_trimmed=$p;
                my $page_trimmed=$page;
@@ -167,6 +167,7 @@ sub scan ($) {
                else {
                        $links{$page}=[];
                }
+               delete $typedlinks{$page};
 
                run_hooks(scan => sub {
                        shift->(
@@ -281,7 +282,7 @@ sub srcdir_check () {
 }
 
 sub verify_src_file ($$) {
-       my $file=decode_utf8(shift);
+       my $file=shift;
        my $dir=shift;
 
        return if -l $file || -d _;
@@ -309,7 +310,7 @@ sub find_src_files () {
        find({
                no_chdir => 1,
                wanted => sub {
-                       my ($file, $page) = verify_src_file($_, $config{srcdir});
+                       my ($file, $page) = verify_src_file(decode_utf8($_), $config{srcdir});
                        if (defined $file) {
                                push @files, $file;
                                if ($pages{$page}) {
@@ -323,7 +324,7 @@ sub find_src_files () {
                find({
                        no_chdir => 1,
                        wanted => sub {
-                               my ($file, $page) = verify_src_file($_, $dir);
+                               my ($file, $page) = verify_src_file(decode_utf8($_), $dir);
                                if (defined $file) {
                                        # avoid underlaydir override
                                        # attacks; see security.mdwn
@@ -346,6 +347,8 @@ sub find_new_files ($) {
        my @new;
        my @internal_new;
 
+       my $times_noted;
+
        foreach my $file (@$files) {
                my $page=pagename($file);
                if (exists $pagesources{$page} && $pagesources{$page} ne $file) {
@@ -357,16 +360,33 @@ sub find_new_files ($) {
                        if (isinternal($page)) {
                                push @internal_new, $file;
                        }
-                       else {
+                       elsif ($config{rcs}) {
+                               if (! $times_noted) {
+                                       debug(sprintf(gettext("querying %s for file creation and modification times.."), $config{rcs}));
+                                       $times_noted=1;
+                               }
+
                                push @new, $file;
-                               if ($config{getctime} && -e "$config{srcdir}/$file") {
+                               if ($config{gettime} && -e "$config{srcdir}/$file") {
                                        eval {
-                                               my $time=rcs_getctime("$config{srcdir}/$file");
-                                               $pagectime{$page}=$time;
+                                               my $ctime=rcs_getctime("$config{srcdir}/$file");
+                                               if ($ctime > 0) {
+                                                       $pagectime{$page}=$ctime;
+                                               }
                                        };
                                        if ($@) {
                                                print STDERR $@;
                                        }
+                                       my $mtime;
+                                       eval {
+                                               $mtime=rcs_getmtime("$config{srcdir}/$file");
+                                       };
+                                       if ($@) {
+                                               print STDERR $@;
+                                       }
+                                       elsif ($mtime > 0) {
+                                               utime($mtime, $mtime, "$config{srcdir}/$file");
+                                       }
                                }
                        }
                        $pagecase{lc $page}=$page;
@@ -392,9 +412,8 @@ sub find_del_files ($) {
                        else {
                                push @del, $pagesources{$page};
                        }
-                       $dellinks{$page}= $links{$page};
                        $links{$page}=[];
-                       $delrenderedfiles{$page}= $renderedfiles{$page};
+                       delete $typedlinks{$page};
                        $renderedfiles{$page}=[];
                        $pagemtime{$page}=0;
                }
@@ -496,6 +515,29 @@ sub remove_unrendered () {
        }
 }
 
+sub link_types_changed ($$) {
+       # each is of the form { type => { link => 1 } }
+       my $new = shift;
+       my $old = shift;
+
+       return 0 if !defined $new && !defined $old;
+       return 1 if !defined $new || !defined $old;
+
+       while (my ($type, $links) = each %$new) {
+               foreach my $link (keys %$links) {
+                       return 1 unless exists $old->{$type}{$link};
+               }
+       }
+
+       while (my ($type, $links) = each %$old) {
+               foreach my $link (keys %$links) {
+                       return 1 unless exists $new->{$type}{$link};
+               }
+       }
+
+       return 0;
+}
+
 sub calculate_changed_links ($$$) {
        my ($changed, $del, $oldlink_targets)=@_;
 
@@ -522,6 +564,14 @@ sub calculate_changed_links ($$$) {
                        }
                        $linkchangers{lc($page)}=1;
                }
+
+               # we currently assume that changing the type of a link doesn't
+               # change backlinks
+               if (!exists $linkchangers{lc($page)}) {
+                       if (link_types_changed($typedlinks{$page}, $oldtypedlinks{$page})) {
+                               $linkchangers{lc($page)}=1;
+                       }
+               }
        }
 
        return \%backlinkchanged, \%linkchangers;
@@ -562,7 +612,7 @@ sub render_dependent ($$$$$$$) {
                if (exists $depends{$p} && ! defined $reason) {
                        foreach my $dep (keys %{$depends{$p}}) {
                                my $sub=pagespec_translate($dep);
-                               next if $@ || ! defined $sub;
+                               next unless defined $sub;
 
                                # only consider internal files
                                # if the page explicitly depends
@@ -630,6 +680,37 @@ sub render_backlinks ($) {
        }
 }
 
+sub gen_autofile ($$$) {
+       my $autofile=shift;
+       my $pages=shift;
+       my $del=shift;
+       
+       if (srcfile($autofile, 1)) {
+               return 0;
+       }
+
+       my ($file, $page) = verify_src_file("$config{srcdir}/$autofile", $config{srcdir});
+       
+       if ((!defined $file) ||
+           (exists $wikistate{$autofiles{$autofile}{plugin}}{autofile_deleted})) {
+               return 0;
+       }
+       
+       if ($pages->{$page}) {
+               return 0;
+       }
+
+       if (grep { $_ eq $file } @$del) {
+               $wikistate{$autofiles{$autofile}{generator}}{autofile_deleted}=1;
+               return 0;
+       }
+
+       $autofiles{$autofile}{generator}->();
+       $pages->{$page}=1;
+       return 1;
+}
+
+
 sub refresh () {
        srcdir_check();
        run_hooks(refresh => sub { shift->() });
@@ -644,26 +725,15 @@ sub refresh () {
                scan($file);
        }
 
-       my %del_hash = map {$_, 1} @$del;
-       while (my $autofile = shift (@autofiles)) {
-               my $page=pagename($autofile);
-    if (exists $del_hash{$page}) {
-                       $links{$page}= $dellinks{$page};
-                       $renderedfiles{$page}= $delrenderedfiles{$page};
-                       delete $del_hash{$page};
+       foreach my $autofile (keys %autofiles) {
+               if (gen_autofile($autofile, $pages, $del)) {
+                       push @{$files}, $autofile;
+                       push @{$new}, $autofile if find_new_files([$autofile]);
+                       push @{$changed}, $autofile if find_changed([$autofile]);
+                       
+                       scan($autofile);
                }
-               if ($pages->{$page}) {
-                       debug(sprintf(gettext("%s has multiple possible source pages"), $page));
-               }
-               $pages->{$page}=1;
-
-               push @{$files}, $autofile;
-               push @{$new}, $autofile if find_new_files([$autofile]);
-               push @{$changed}, $autofile if find_changed([$autofile]);
-
-               scan($autofile);
        }
-       $del = [keys %del_hash];
 
        calculate_links();
        
@@ -701,6 +771,17 @@ sub refresh () {
        }
 }
 
+sub clean_rendered {
+       lockwiki();
+       loadindex();
+       remove_unrendered();
+       foreach my $page (keys %oldrenderedfiles) {
+               foreach my $file (@{$oldrenderedfiles{$page}}) {
+                       prune($config{destdir}."/".$file);
+               }
+       }
+}
+
 sub commandline_render () {
        lockwiki();
        loadindex();