X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/2217e3d5bbb377bb40a5701e90341f011c49a536..9a173d91bbeceb0514bb0ae6c32176eadab94d41:/IkiWiki/Plugin/toc.pm

diff --git a/IkiWiki/Plugin/toc.pm b/IkiWiki/Plugin/toc.pm
index 639cae4a9..4d29e7040 100644
--- a/IkiWiki/Plugin/toc.pm
+++ b/IkiWiki/Plugin/toc.pm
@@ -4,17 +4,27 @@ package IkiWiki::Plugin::toc;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use HTML::Parser;
 
-sub import { #{{{
+sub import {
+	hook(type => "getsetup", id => "toc", call => \&getsetup);
 	hook(type => "preprocess", id => "toc", call => \&preprocess);
 	hook(type => "format", id => "toc", call => \&format);
-} # }}}
+}
+
+sub getsetup () {
+	return
+		plugin => {
+			safe => 1,
+			rebuild => undef,
+			section => "widget",
+		},
+}
 
 my %tocpages;
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
 	my %params=@_;
 
 	if ($params{page} eq $params{destpage}) {
@@ -31,9 +41,9 @@ sub preprocess (@) { #{{{
 		# right.
 		return "";
 	}
-} # }}}
+}
 
-sub format (@) { #{{{
+sub format (@) {
 	my %params=@_;
 	my $content=$params{content};
 	
@@ -44,24 +54,32 @@ sub format (@) { #{{{
 	my $page="";
 	my $index="";
 	my %anchors;
-	my $curlevel;
-	my $startlevel=0;
+	my $startlevel=($params{startlevel} ? $params{startlevel} : 0);
+	my $curlevel=$startlevel-1;
 	my $liststarted=0;
 	my $indent=sub { "\t" x $curlevel };
 	$p->handler(start => sub {
-		my $tagname=shift;
-		my $text=shift;
+		my ($tagname, $text, $attr) = @_;
 		if ($tagname =~ /^h(\d+)$/i) {
 			my $level=$1;
 			my $anchor="index".++$anchors{$level}."h$level";
 			$page.="$text<a name=\"$anchor\"></a>";
-	
-			# Take the first header level seen as the topmost level,
+			# if the heading already has a unique ID, use that instead in TOC
+			if ($attr->{id}) {
+				$anchor = $attr->{id};
+			}
+
+			# Unless we're given startlevel as a parameter,
+			# take the first header level seen as the topmost level,
 			# even if there are higher levels seen later on.
 			if (! $startlevel) {
 				$startlevel=$level;
 				$curlevel=$startlevel-1;
 			}
+			elsif (defined $params{startlevel} &&
+			       $level < $params{startlevel}) {
+			    return;
+			}
 			elsif ($level < $startlevel) {
 				$level=$startlevel;
 			}
@@ -109,7 +127,7 @@ sub format (@) { #{{{
 		else {
 			$page.=$text;
 		}
-	}, "tagname, text");
+	}, "tagname, text, attr");
 	$p->handler(default => sub { $page.=join("", @_) }, "text");
 	$p->parse($content);
 	$p->eof;