summaryrefslogtreecommitdiff
path: root/IkiWiki/Plugin/autoindex.pm
blob: 825633d5a319db2a416ff3a88fbf2cc2a680eb00 (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. next if $dir eq $IkiWiki::Plugin::transient::transientdir;
  58. chdir($dir) || next;
  59. find({
  60. no_chdir => 1,
  61. wanted => sub {
  62. my $file=decode_utf8($_);
  63. $file=~s/^\.\/?//;
  64. return unless length $file;
  65. if (IkiWiki::file_pruned($file)) {
  66. $File::Find::prune=1;
  67. }
  68. elsif (! -l $_) {
  69. my ($f) = $file =~ /$config{wiki_file_regexp}/; # untaint
  70. return unless defined $f;
  71. return if $f =~ /\._([^.]+)$/; # skip internal page
  72. if (! -d _) {
  73. $pages{pagename($f)}=1;
  74. }
  75. elsif ($dir eq $config{srcdir}) {
  76. $dirs{$f}=1;
  77. }
  78. }
  79. }
  80. }, '.');
  81. chdir($origdir) || die "chdir $origdir: $!";
  82. }
  83. # Compatibility code.
  84. #
  85. # {deleted} contains pages that have been deleted at some point.
  86. # This plugin used to delete from the hash sometimes, but no longer
  87. # does; in [[todo/autoindex_should_use_add__95__autofile]] Joey
  88. # thought the old behaviour was probably a bug.
  89. #
  90. # The effect of listing a page in {deleted} was to avoid re-creating
  91. # it; we migrate these pages to {autofile} which has the same effect.
  92. # However, {autofile} contains source filenames whereas {deleted}
  93. # contains page names.
  94. my %deleted;
  95. if (ref $wikistate{autoindex}{deleted}) {
  96. %deleted=%{$wikistate{autoindex}{deleted}};
  97. delete $wikistate{autoindex}{deleted};
  98. }
  99. elsif (ref $pagestate{index}{autoindex}{deleted}) {
  100. # an even older version
  101. %deleted=%{$pagestate{index}{autoindex}{deleted}};
  102. delete $pagestate{index}{autoindex};
  103. }
  104. if (keys %deleted) {
  105. foreach my $dir (keys %deleted) {
  106. my $file=newpagefile($dir, $config{default_pageext});
  107. $wikistate{autoindex}{autofile}{$file} = 1;
  108. }
  109. }
  110. foreach my $dir (keys %dirs) {
  111. if (! exists $pages{$dir} && grep /^$dir\/.*/, keys %pages) {
  112. genindex($dir);
  113. }
  114. }
  115. }
  116. 1