summaryrefslogtreecommitdiff
path: root/IkiWiki/Plugin/autoindex.pm
blob: d0261858104cdc2783709c7fafda468b94b975b4 (plain)
  1. #!/usr/bin/perl
  2. package IkiWiki::Plugin::autoindex;
  3. use warnings;
  4. use strict;
  5. use IkiWiki 3.00;
  6. use Encode;
  7. sub import {
  8. hook(type => "getsetup", id => "autoindex", call => \&getsetup);
  9. hook(type => "refresh", id => "autoindex", call => \&refresh);
  10. IkiWiki::loadplugin("transient");
  11. }
  12. sub getsetup () {
  13. return
  14. plugin => {
  15. safe => 1,
  16. rebuild => 0,
  17. },
  18. autoindex_commit => {
  19. type => "boolean",
  20. example => 1,
  21. default => 1,
  22. description => "commit autocreated index pages",
  23. safe => 1,
  24. rebuild => 0,
  25. },
  26. }
  27. sub genindex ($) {
  28. my $page=shift;
  29. my $file=newpagefile($page, $config{default_pageext});
  30. add_autofile($file, "autoindex", sub {
  31. my $message = sprintf(gettext("creating index page %s"),
  32. $page);
  33. debug($message);
  34. my $dir = $config{srcdir};
  35. if (! $config{autoindex_commit}) {
  36. $dir = $IkiWiki::Plugin::transient::transientdir;
  37. }
  38. my $template = template("autoindex.tmpl");
  39. $template->param(page => $page);
  40. writefile($file, $dir, $template->output);
  41. if ($config{rcs} && $config{autoindex_commit}) {
  42. IkiWiki::disable_commit_hook();
  43. IkiWiki::rcs_add($file);
  44. IkiWiki::rcs_commit_staged(message => $message);
  45. IkiWiki::enable_commit_hook();
  46. }
  47. });
  48. }
  49. sub refresh () {
  50. eval q{use File::Find};
  51. error($@) if $@;
  52. eval q{use Cwd};
  53. error($@) if $@;
  54. my $origdir=getcwd();
  55. my (%pages, %dirs);
  56. foreach my $dir ($config{srcdir}, @{$config{underlaydirs}}, $config{underlaydir}) {
  57. chdir($dir) || next;
  58. find({
  59. no_chdir => 1,
  60. wanted => sub {
  61. my $file=decode_utf8($_);
  62. $file=~s/^\.\/?//;
  63. return unless length $file;
  64. if (IkiWiki::file_pruned($file)) {
  65. $File::Find::prune=1;
  66. }
  67. elsif (! -l $_) {
  68. my ($f) = $file =~ /$config{wiki_file_regexp}/; # untaint
  69. return unless defined $f;
  70. return if $f =~ /\._([^.]+)$/; # skip internal page
  71. if (! -d _) {
  72. $pages{pagename($f)}=1;
  73. }
  74. elsif ($dir eq $config{srcdir}) {
  75. $dirs{$f}=1;
  76. }
  77. }
  78. }
  79. }, '.');
  80. chdir($origdir) || die "chdir $origdir: $!";
  81. }
  82. # Compatibility code.
  83. #
  84. # {deleted} contains pages that have been deleted at some point.
  85. # This plugin used to delete from the hash sometimes, but no longer
  86. # does; in [[todo/autoindex_should_use_add__95__autofile]] Joey
  87. # thought the old behaviour was probably a bug.
  88. #
  89. # The effect of listing a page in {deleted} was to avoid re-creating
  90. # it; we migrate these pages to {autofile} which has the same effect.
  91. # However, {autofile} contains source filenames whereas {deleted}
  92. # contains page names.
  93. my %deleted;
  94. if (ref $wikistate{autoindex}{deleted}) {
  95. %deleted=%{$wikistate{autoindex}{deleted}};
  96. delete $wikistate{autoindex}{deleted};
  97. }
  98. elsif (ref $pagestate{index}{autoindex}{deleted}) {
  99. # an even older version
  100. %deleted=%{$pagestate{index}{autoindex}{deleted}};
  101. delete $pagestate{index}{autoindex};
  102. }
  103. if (keys %deleted) {
  104. foreach my $dir (keys %deleted) {
  105. my $file=newpagefile($dir, $config{default_pageext});
  106. $wikistate{autoindex}{autofile}{$file} = 1;
  107. }
  108. }
  109. foreach my $dir (keys %dirs) {
  110. if (! exists $pages{$dir} && grep /^$dir\/.*/, keys %pages) {
  111. genindex($dir);
  112. }
  113. }
  114. }
  115. 1