<?php
//
// Web Page Auto Menu
// (c) 2011 Denis Sureau - Licence GPL 3
// Web: www.scriptol.com
// Work on a single Web page. Build a menu with anchors and links to headings
//
// Processing
// - Retrieve a previous generated menu with anchors.
// - Extract heading tags, h2 etc.
// - Build an unique id for each, add it to all heading tags.
// - Build/update a hierarchical indented menu with links to these tags.
// - Insert the menu after the <h1> tag or replace the previous menu in place.
// - You can move the menu manually.
//
// Makes use of the Simple HTML parser by Jose Solorzano (https://sourceforge.net/projects/php-html/)
//
require("simple_html_dom.php");
$legend="Summary";
$idlist=array();
function getMax($tag,$doc)
{
$maximum=0;
$ctr=0;
$x=null;
$temp="";
$tags=$doc->find($tag);
if(count($tags)>0)
{
reset($tags);
do
{
$x= current($tags);
$temp=trim($x->id);
if($temp!="")
{
$ctr=intVal(intval(substr($temp,2)));
$maximum=intVal(max($maximum,$ctr));
}
}
while(!(next($tags) === false));
}
return $maximum;
}
function getTags($doc,$tag,$counter)
{
$x=null;
$tags=$doc->find($tag);
if(count($tags)>0)
{
reset($tags);
do
{
$x= current($tags);
if(trim($x->id)==="")
{
if($x->id!="")
{
global $idlist;
array_push($idlist,$x->id);
}
else
{
$counter+=1;
$newid=$tag.strval($counter);
$x->id=$newid;
global $idlist;
array_push($idlist,$newid);
}
}
}
while(!(next($tags) === false));
}
return;
}
$doc=new simple_html_dom();
$headings=array();
$depthlevel=0;
function buildMenu($element)
{
while(true)
{
do
{
if($element===null)
{
break 2;
}
if($element===false)
{
break 2;
}
if(in_array($element->tag,array("h2","h3","h4","h5","h6")))
{
$id=$element->id;
$anchor=$element->innertext;
$level=intVal(intval($element->tag{1}));
global $depthlevel;
if($level<=$depthlevel)
{
global $headings;
$headings[$id]=$anchor;
}
}
$n=$element->first_child();
if($n!=false)
{
buildMenu($n);
}
$element=$element->next_sibling();
} while(false);
}
return;
}
$menu="";
$licounter=0;
function addMenu($currentLevel)
{
global $menu;
$menu.="<ul>\n";
global $headings;
$id=key($headings);
$anchor=$headings[$id];
array_shift($headings);
$menu.="<li><a href='#$id'>$anchor</a></li>\n";
global $licounter;
$licounter+=1;
while(count($headings)>0)
{
do
{
$id=key($headings);
$level=$id{1};
if($level<$currentLevel)
{
break 2;
}
if($level>$currentLevel)
{
addMenu($level);
}
else
{
$anchor=$headings[$id];
array_shift($headings);
$menu.="<li><a href='#$id'>$anchor</a></li>\n";
$licounter+=1;
}
} while(false);
}
$menu.="</ul>\n";
return;
}
function syntax()
{
echo "Web Page Auto Menu - (c) 2011 Scriptol.com - Freeware", "\n";
echo "Syntax:", "\n";
echo " php [-hn] automenu.php [path]filename.html", "\n";
echo "Option:", "\n";
echo " -h2 .. -hn depth level to take into account", "\n";
echo "Builds a menu from headings in a HTML page with links.", "\n";
exit(0);
return;
}
function main($argnum,$argv)
{
global $legend;
global $licounter;
if($argnum<2)
{
syntax();
}
global $depthlevel;
$depthlevel=3;
$pathindex=1;
reset($argv);
do
{
$param= current($argv);
if(strlen($param)!=3)
{
continue;
}
if(substr($param,0,2)!="-h")
{
continue;
}
$depthlevel=intVal(intval($param{2}));
$pathindex=2;
}
while(!(next($argv) === false));
if(($depthlevel<2))
{
syntax();
}
$path=$argv[$pathindex];
global $doc;
$doc=file_get_html($path);
$content=$doc->plaintext;
echo "Starting counters to";
for($i=2;$i<=$depthlevel;$i++)
{
$htag="h$i";
$counter=getMax($htag,$doc);
echo " $htag=$counter";
getTags($doc,$htag,$counter);
}
echo "", "\n";
$h1=$doc->find("h1");
if(count($h1)===0)
{
die("Add an H1 tag to the page.");
}
$root=$h1[0];
$x=$root->next_sibling();
buildMenu($x);
global $menu;
$menu="\n<fieldset id=\"automenu\">\n<legend>$legend</legend>\n";
addMenu("2");
$menu.="</fieldset>\n";
$already=$doc->find("fieldset[id=automenu]");
$update=null;
if(count($already)>0)
{
$root=$already[0];
$root->outertext=str_get_html($menu);
$update="updated";
}
else
{
$root->outertext.=str_get_html($menu);
$update="generated";
}
file_put_contents($path,$doc);
echo "Menu $update in $path with $licounter links.", "\n";
return 0;
}
main(intVal($argc),$argv);
?>