Location: PHPKode > scripts > Automenu > automenu/automenu.php
<?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);

?>
Return current item: Automenu