123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- use strict;
- use v5.10;
- AddModuleDescription('toc-headers.pl');
- our ($q, $bol, %Page, @MyRules);
- our ($MinTocSize, $OrderedLists);
- push(@MyRules, \&HeadersRule);
- $MinTocSize = 4;
- $OrderedLists = 0;
- my $TocCounter = 0;
- my $TocShown = 0;
- sub HeadersRule {
- my $html = undef;
- if (!$TocShown) {
- $html = CloseHtmlEnvironments() . TocHeadings() . AddHtmlEnvironment('p');
- $TocShown = 1;
- }
- if ($bol && (m/\G((.+?)[ \t]*\n(---+|===+)[ \t]*\n)/cg)) {
- $html .= CloseHtmlEnvironments();
- $TocCounter++;
- $html .= "<a name=\"#$TocCounter\"></a>";
- if (substr($3,0,1) eq '=') {
- $html .= $q->h2($2);
- } else {
- $html .= $q->h3($2);
- }
- $html .= AddHtmlEnvironment('p');
- }
- return $html;
- }
- sub TocHeadings {
- my $oldpos = pos;
- my $page = $Page{text};
-
- foreach my $tag ('nowiki', 'pre', 'code') {
- $page =~ s|<$tag>(.*\n)*?</$tag>||gi;
- }
- my $Headings = "<h2>" . T('Contents') . "</h2>";
- my $HeadingsLevel = undef;
- my $HeadingsLevelStart = undef;
- my $count = 1;
- my $tag = $OrderedLists ? 'ol' : 'ul';
- while ($page =~ m/((.+?)[ \t]*\n(---+|===+)[ \t]*\n)/g) {
- my $depth = (substr($3,0,1) eq '=') ? 2 : 3;
- my $text = $2;
- next unless $text;
- my $link = "$count"; #1, #2, etc. links seem to work fine
- $text = QuoteHtml($text);
- if (not defined $HeadingsLevelStart) {
- # $HeadingsLevel is set to $depth - 1 so that we get an opening
- # of the list. We need $HeadingsLevelStart to close all open
- # tags at the end.
- $HeadingsLevel = $depth - 1;
- $HeadingsLevelStart = $depth - 1;
- }
- $count++;
- # if the first subheading is has depth 2, then
- # $HeadingsLevelStart is 1, and later subheadings may not be
- # at level 1 or below.
- $depth = $HeadingsLevelStart + 1 if $depth <= $HeadingsLevelStart;
- # the order of the three expressions is important!
- while ($HeadingsLevel > $depth) {
- $Headings .= "</li></$tag>";
- $HeadingsLevel--;
- }
- if ($HeadingsLevel == $depth) {
- $Headings .= '</li><li>';
- }
- while ($HeadingsLevel < $depth) {
- $Headings .= "<$tag class=\"h$depth\"><li>";
- $HeadingsLevel++;
- }
- $Headings .= "<a href=\"#$link\">$text</a>";
- }
- while ($HeadingsLevel > $HeadingsLevelStart) {
- $Headings .= "</li></$tag>";
- $HeadingsLevel--;
- }
- pos = $oldpos;
- return '' if $count <= $MinTocSize;
- return $q->div({-class=>'toc'}, $Headings)
- if $Headings;
- }
|