2 # Table Of Contents generator
3 package IkiWiki
::Plugin
::toc
;
11 hook
(type
=> "getsetup", id
=> "toc", call
=> \
&getsetup
);
12 hook
(type
=> "preprocess", id
=> "toc", call
=> \
&preprocess
);
13 hook
(type
=> "format", id
=> "toc", call
=> \
&format
);
30 if ($params{page
} eq $params{destpage
}) {
31 $params{levels
}=1 unless exists $params{levels
};
33 # It's too early to generate the toc here, so just record the
35 $tocpages{$params{destpage
}}=\
%params;
37 return "\n<div class=\"toc\"></div>\n";
40 # Don't generate toc in an inlined page, doesn't work
48 my $content=$params{content
};
50 return $content unless exists $tocpages{$params{page
}};
51 %params=%{$tocpages{$params{page
}}};
53 my $p=HTML
::Parser
->new(api_version
=> 3);
57 my $startlevel=($params{startlevel
} ?
$params{startlevel
} : 0);
58 my $curlevel=$startlevel-1;
60 my $indent=sub { "\t" x
$curlevel };
61 $p->handler(start
=> sub {
64 if ($tagname =~ /^h(\d+)$/i) {
66 my $anchor="index".++$anchors{$level}."h$level";
67 $page.="$text<a name=\"$anchor\"></a>";
69 # Unless we're given startlevel as a parameter,
70 # take the first header level seen as the topmost level,
71 # even if there are higher levels seen later on.
74 $curlevel=$startlevel-1;
76 elsif (defined $params{startlevel
} &&
77 $level < $params{startlevel
}) {
80 elsif ($level < $startlevel) {
84 return if $level - $startlevel >= $params{levels
};
86 if ($level > $curlevel) {
87 while ($level > $curlevel + 1) {
88 $index.=&$indent."<ol>\n";
90 $index.=&$indent."<li class=\"L$curlevel\">\n";
92 $index.=&$indent."<ol>\n";
96 elsif ($level < $curlevel) {
97 while ($level < $curlevel) {
98 $index.=&$indent."</li>\n" if $curlevel;
100 $index.=&$indent."</ol>\n";
105 $index.=&$indent."</li>\n" unless $liststarted;
107 $index.=&$indent."<li class=\"L$curlevel\">".
108 "<a href=\"#$anchor\">";
110 $p->handler(text
=> sub {
112 $index.=join("", @_);
114 $p->handler(end
=> sub {
116 if ($tagname =~ /^h(\d+)$/i) {
117 $p->handler(text
=> undef);
118 $p->handler(end
=> undef);
128 $p->handler(default => sub { $page.=join("", @_) }, "text");
132 while ($startlevel && $curlevel >= $startlevel) {
133 $index.=&$indent."</li>\n" if $curlevel;
135 $index.=&$indent."</ol>\n";
138 $page=~s/(<div class=\"toc\">)/$1\n$index/;