xemacsweb / toc.gp

#
# This recipe generates a table of contents (within a file) complete
# with jumps to the relevant bits including substituting in anchors.
# It uses <H?> tags to find the relevant entries where '?' is a level
# of header. You specify the header level to use (e.g. start at H2's 
# and build the TOC from there) 
#
# This is a simple one level TOC... An obvious enhancement is to have it
# recurse within say a h1 block for h2s ,h3s etc
# Submitted by Joe Vaughan joev@freddyfrog.com  (11/06/1999)
# 
# initialisation: put <!-- _GP_ recipe($root/include/toc.gp) --> in one 
# of the parsed files e.g. your template or include it at startup using
# 'genpage -r toc.gp'
#
# use: Place a <!-- _GP_ content(qq{TOC}) --> wherever you want the TOC 
#      to appear and place <!-- _GP_ toc(start-header-level) --> 
#      somewhere that it'll get parsed late or last in the file.
#  

sub toc {
  my $startlevel = shift;
  my $stoplevel = shift;
  
  if ($startlevel < 1) { $startlevel = 1; }
  if ($startlevel > 7) { $startlevel = 7; }
  if (defined($stoplevel)) {
    if ($stoplevel < $startlevel) { $stoplevel = $startlevel; }
    if ($stoplevel > 7) { $stoplevel = 7; }
  }
  else {
    $stoplevel = 7;
  }
  my $anchornum = 0;
  my $tempbit = $left . "###TOC-SPLIT-HERE###" .$right;
  my $pattern = qr{^(.*?)<h([0-9])>(?!<a name)\s*(.*?)</h.>(.*)\$};
  my $toc = "<ul>\n";
  my $tablevel = $startlevel;
  my ($leftbit, $level,$middlebit, $rightbit );

  while ($tempbit =~ /$pattern/is ) {
    if ($tablevel < $startlevel ) { 
      $tablevel = $startlevel;
    }
    ($leftbit, $level,$middlebit, $rightbit ) = ($1, $2, $3, $4);
    if ($level >= $startlevel && $level <= $stoplevel) {
      if ($level < $tablevel) {
	for ($i = 0; $i<($tablevel-$level);$i++) {
	  $toc .="</ul>";
	}
      }
      else {
	if ($level > $tablevel) {
	  for ($i = 0; $i<($level-$tablevel);$i++) {
	    $toc .="<ul>";
	  }
	}
      }

      $tablevel = $level;
      $toc= $toc . "<li><a href=\"#$anchornum\">$middlebit</a></li>\n";
      $middlebit = "<h$level><a name=\"$anchornum\">" . $middlebit . "</a></h$level>";
      $anchornum++;
    }
    else {
      $middlebit = "<h$level><a name=\"\">" . $middlebit . "</a></h$level>";
    }
    $tempbit = $leftbit . $middlebit . $rightbit; 
  }
  $toc = $toc . "</ul>\n";
  # Second pass replaces the content("TOC") error tag (from earlier 
  # pass content() filtering 
  $pattern = "^(.*?)<!-- content: undefined tag: TOC -->(.*)\$";
  while ($tempbit =~ /$pattern/is ) {
    $tempbit = $1 . $toc . $2;
  }
  
  ($left,$right) = split ("###TOC-SPLIT-HERE###",$tempbit);
  
  return "<!-- Table of Contents has been autoinserted by recipe TOC.gp -->";
}

return ("<!-- Genpage recipe TOC.gp included -->");
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.