SimpleTableOfContents
<< My PmWiki | Cookbook-V1 | Embedded Gallery >>
Note: The recipes here are for PmWiki versions 0.6 and 1.0 only. For PmWiki 2.0 recipes, see Cookbook.
Goal
Automatically generate a Table of Contents for pages with many headings.
PmWiki (1.0.13) doesn't come with a TOC feature, as PITS/00027 said, there feature request suspended for there already a Cookbook PageTableOfContents. But the cookbook TOC module seems a little complicated for me. All I want is a autogenerated TOC from all levels of headings in a page, just like the WikiPedia style.
Solution
Add some script to pmwiki.php to generate a list of all levels of headings. Feature:
- auto generate TOC list for all level headings
- use heading text as the target name
- do not need to modify exist wiki text
First, add a function named ProcessTOC in pmwiki.php to insert Wiki text for TOC before print text begin.
|
function ProcessTOC($text) { $tocText = '';
$bodyText = '';
$lines = explode("\n",$text);
$lineNo = 0;
$minLevel = 9;
foreach($lines as $x) {
$lineNo += 1;
if (preg_match("/^(!{1,6})/",$x,$match)) {
$level = strlen($match[1]);
if ($level < $minLevel ) $minLevel = $level; # record the min heading level
# get the heading text, rid leading ! and white space
$strAnchor = preg_replace("/^(!{1,6}\s*)/","",$x);
# 'T_' for target, encode the heading text
$strAnchor = 'T_'.preg_replace("/[+|%]/","_",urlencode($strAnchor));
# add a line of toc text
$toc = strlen($match[1])."","";
$tocText .= $toc."\n";
# add a target before heading text
$x = "\n".$x;
}
$bodyText .= $x."\n"; # add a line of body text
}
$toc = "";
if ($tocText != "") {
# use substr to rid the tailing '\n'
$lines = explode("\n",substr($tocText,0, strlen($tocText)-1) );
foreach($lines as $x) {
$level = $x[0];
# set a correct number of '*'
$toc .= str_repeat('*', $level - $minLevel +1 ).substr($x,1)."\n";
}
# add table border for TOC
$tocText = "(:table border=1 cellpadding=10:)
\n(:cell:) \n".$toc."(:tableend:) \n\n"; } return $tocText.$bodyText; } |
Then, at the beginning lines of PrintText function, change
if ($text=="") $text=$Text;
to
if ($text=="") $text = ProcessTOC($Text);
That's OK
For Example, these headings
!! North America !!! New York !!! Washington !! Asia !!! China !!!! Shanghai !!! Japan
will turn to a TOC section of :

Discussion
I've only used PmWiki for a week, and am a PHP newhand (ProcessTOC is the first fuction code I write in PHP), so the solution here a very simple one but seems convenient for myself.
Consider a better solution:
- Is it possible to write a module script for this and do not modify pmwiki.php ?
- If targets defined in the heading text line, the result is error. the line of heading should not contain other targets, if need a special target name, define it in the line before heading line. (This happens to PmWiki.TextFormattingRules)
- Compare to WikiPedia, the TOC need these features :
- define __notoc__ for pages
- toc section show/hide
- do not show TOC when headings less than two lines
- add outline style number before toc heading text. (e.g. 1.2.2)
See Also
History
2004.11.22 - Initial idea by LiuPing -> mailto:lp_ [snail] 163 [period] net
Comments & Bugs
Contributors
- LiuPing -> mailto:lp_ [snail] 163 [period] net
pmwiki-2.5.4 -- Last modified by {{}}