]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/blobdiff - IkiWiki/Plugin/toc.pm
meta: Error if we can't parse dates because Date::Parse is missing
[git.ikiwiki.info.git] / IkiWiki / Plugin / toc.pm
index dff9d9aa5356e5928de0a9ddd654217f2165af84..4d29e704050f65dd8d22b57f655a1a2b70e19a57 100644 (file)
@@ -4,26 +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 () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
-} #}}}
+}
 
 my %tocpages;
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
 
        if ($params{page} eq $params{destpage}) {
@@ -40,9 +41,9 @@ sub preprocess (@) { #{{{
                # right.
                return "";
        }
-} # }}}
+}
 
-sub format (@) { #{{{
+sub format (@) {
        my %params=@_;
        my $content=$params{content};
        
@@ -53,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;
                        }
@@ -118,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;