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 <a href=\"#toc$toccount\">$2</a></span><br>\n"; 84 $toc .= "<div class=\"toc$1\">$secno <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 $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