0e30b9900e1ea3011789ddc6561961d610208773
[ikiwiki.git] / IkiWiki / Plugin / autoindex.pm
1 #!/usr/bin/perl
2 package IkiWiki::Plugin::autoindex;
3
4 use warnings;
5 use strict;
6 use IkiWiki 2.00;
7 use Encode;
8
9 sub import { #{{{
10         hook(type => "getsetup", id => "autoindex", call => \&getsetup);
11         hook(type => "refresh", id => "autoindex", call => \&refresh);
12 } # }}}
13
14 sub getsetup () { #{{{
15         return
16                 plugin => {
17                         safe => 1,
18                         rebuild => 0,
19                 },
20 } #}}}
21
22 sub genindex ($) { #{{{
23         my $page=shift;
24         my $file=$page.".".$config{default_pageext};
25         my $template=template("autoindex.tmpl");
26         $template->param(page => $page);
27         writefile($file, $config{srcdir}, $template->output);
28         if ($config{rcs}) {
29                 IkiWiki::rcs_add($file);
30         }
31 } #}}}
32
33 sub refresh () { #{{{
34         eval q{use File::Find};
35         error($@) if $@;
36
37         my (%pages, %dirs);
38         foreach my $dir ($config{srcdir}, @{$config{underlaydirs}}, $config{underlaydir}) {
39                 find({
40                         no_chdir => 1,
41                         wanted => sub {
42                                 $_=decode_utf8($_);
43                                 if (IkiWiki::file_pruned($_, $dir)) {
44                                         $File::Find::prune=1;
45                                 }
46                                 elsif (! -l $_) {
47                                         my ($f)=/$config{wiki_file_regexp}/; # untaint
48                                         return unless defined $f;
49                                         $f=~s/^\Q$dir\E\/?//;
50                                         return unless length $f;
51                                         return if $f =~ /\._([^.]+)$/; # skip internal page
52                                         if (! -d _) {
53                                                 $pages{pagename($f)}=1;
54                                         }
55                                         elsif ($dir eq $config{srcdir}) {
56                                                 $dirs{$f}=1;
57                                         }
58                                 }
59                         }
60                 }, $dir);
61         }
62
63         my @needed;
64         foreach my $dir (keys %dirs) {
65                 if (! exists $pages{$dir} && grep /^$dir\/.*/, keys %pages) {
66                         push @needed, $dir;
67                 }
68         }
69         
70         if (@needed) {
71                 if ($config{rcs}) {
72                         IkiWiki::disable_commit_hook();
73                 }
74                 genindex($_) foreach @needed;
75                 if ($config{rcs}) {
76                         IkiWiki::rcs_commit_staged(
77                                 gettext("automatic index generation"),
78                                 undef, undef);
79                         IkiWiki::enable_commit_hook();
80                 }
81         }
82 } #}}}
83
84 1