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.3.38 -- Last modified by {{}}?