1#!/usr/bin/perl -w
2use strict;
3
4# Add a table of contents to a basic HTML file.
5# Useless if you have lots of layout, this is just for
6# document-structured HTML with <h1>s and things.
7
8# For a table of contents, surround all the stuff you want tabulated
9# by a <contents>...</contents> pair.  <contents> will be replaced by
10# a TOC for all <hX> tags from there up to </contents>, and <hX> will
11# be given <a name=...> provided the </hX> is also present.
12
13my $tocmode = 0;
14my $outbuf;
15my $toc;
16my $toccount = 1;
17
18my $ilevel = 0;
19my $ibase = -1;
20
21my $enddiv = "";
22my $oddeven = "oddcontent";
23my @sectionNumbers;
24
25sub indentTo {
26    my $level = shift;
27    if ($ibase < 0) { $ibase = $level; $ilevel = $ibase-1; }
28    if ($level == 0 and $ibase > 0) { $level = $ibase-1; }
29
30    while ($level > $ilevel) {
31#        $toc .= "<ul>";
32        $ilevel ++;
33    }
34    while ($level < $ilevel) {
35        undef $sectionNumbers[$ilevel];
36#        $toc .= "</ul>";
37        $ilevel --;
38    }
39}
40
41sub newSectionNumber {
42    my $level = shift;
43    my $i = ($ibase < 0 ? 1 : $ibase);
44    my $secno;
45    while ($i <= $level) {
46        if (!defined $sectionNumbers[$i]) { $sectionNumbers[$i] = 1; }
47        elsif ($i == $level) { ++$sectionNumbers[$i]; }
48        $secno .= $sectionNumbers[$i] . ".";
49        ++$i;
50    }
51#    chop $secno;
52    $secno;
53}
54
55while (<>) {
56    if (!$tocmode) {
57        m{<contents>}i and do {
58            s{<contents>}{}i;
59            $tocmode = 1;
60        }
61    }
62    if (!$tocmode) { print; next; }
63
64    # okay, we're building up the table-of-contents and storing
65    # ongoing data into $outbuf in the meantime
66
67    m{</contents>}i and do {
68        $tocmode = 0;
69        if (!defined $toc) { print "$outbuf\n$enddiv\n"; }
70        else {
71            indentTo 0;
72#            print "<h2>Contents</h2>\n";
73	    print "$toc\n$outbuf\n$enddiv\n";
74        }
75        next;
76    };
77
78    m{<h(\d)>(.*?)</h(\d)>}i and do {
79        warn "<H$1> closed by <H$3>" if ($1 != $3);
80        indentTo $1;
81        my $secno = newSectionNumber $1;
82
83#        $toc .= "<span class=\"toc$1\">$secno &nbsp;<a href=\"#toc$toccount\">$2</a></span><br>\n";
84        $toc .= "<div class=\"toc$1\">$secno &nbsp;<a href=\"#toc$toccount\">$2</a></div>\n";
85
86        s{(<h\d>)(.*?)(</h\d>)}
87         {$enddiv<div class="$oddeven"><a name="toc$toccount"></a>$1$secno &nbsp;$2$3}i;
88
89        $enddiv = "</div>";
90        $oddeven = ($oddeven eq "oddcontent" ? "evencontent" : "oddcontent");
91        $toccount++;
92    };
93
94    $outbuf .= $_;
95}
96
97if ($tocmode) {
98    warn "Unclosed <contents>";
99    indentTo 0;
100#    print "<h2>Contents</h2>\n";
101    print "$toc\n$outbuf";
102}
103
104