src/TocGenerator.php
public function getMenu($markup, $topLevel = 1, $depth = 6)
    {
        // Setup an empty menu object
        $menu = $this->menuFactory->createItem('TOC');

        // Empty?  Return empty menu item
        if (trim($markup) == '') {
            return $menu;
        }

        // Parse HTML
        $tagsToMatch = $this->determineHeaderTags($topLevel, $depth);


        // Initial settings
        $lastElem = $menu;

        // Do it...
        $domDocument = $this->domParser->loadHTML($markup);
        foreach ($this->traverseHeaderTags($domDocument, $topLevel, $depth) as $node) {

            // Skip items without IDs
            if ( ! $node->hasAttribute('id')) {
                continue;
            }

            // Get the TagName and the level
            $tagName = $node->tagName;
            $level   = array_search(strtolower($tagName), $tagsToMatch) + 1;

            // Determine parent item which to add child
            if ($level == 1) {
                $parent = $menu;
            }
            elseif ($level == $lastElem->getLevel()) {
                $parent = $lastElem->getParent();
            }
            elseif ($level > $lastElem->getLevel()) {
                $parent = $lastElem;
                for ($i = $lastElem->getLevel(); $i < ($level - 1); $i++) {
                    $parent = $parent->addChild('');
                }
            }
            else { //if ($level < $lastElem->getLevel())
                $parent = $lastElem->getParent();
                while ($parent->getLevel() > $level - 1) {
                    $parent = $parent->getParent();
                }
            }

            $lastElem = $parent->addChild(
                $node->getAttribute('title') ?: $node->textContent,
                ['uri' => '#' . $node->getAttribute('id')]
            );
        }

        return $menu;
    }
public function getMenu($markup, $topLevel = 1, $depth = 6)
    {
        // Setup an empty menu object
        $menu = $this->menuFactory->createItem('TOC');

        // Empty?  Return empty menu item
        if (trim($markup) == '') {
            return $menu;
        }

        // Parse HTML
        $tagsToMatch = $this->determineHeaderTags($topLevel, $depth);


        // Initial settings
        $lastElem = $menu;

        // Do it...
        $domDocument = $this->domParser->loadHTML($markup);
        foreach ($this->traverseHeaderTags($domDocument, $topLevel, $depth) as $node) {

            // Skip items without IDs
            if ( ! $node->hasAttribute('id')) {
                continue;
            }

            // Get the TagName and the level
            $tagName = $node->tagName;
            $level   = array_search(strtolower($tagName), $tagsToMatch) + 1;

            // Determine parent item which to add child
            if ($level == 1) {
                $parent = $menu;
            }
            elseif ($level == $lastElem->getLevel()) {
                $parent = $lastElem->getParent();
            }
            elseif ($level > $lastElem->getLevel()) {
                $parent = $lastElem;
                for ($i = $lastElem->getLevel(); $i < ($level - 1); $i++) {
                    $parent = $parent->addChild('');
                }
            }
            else { //if ($level < $lastElem->getLevel())
                $parent = $lastElem->getParent();
                while ($parent->getLevel() > $level - 1) {
                    $parent = $parent->getParent();
                }
            }

            $lastElem = $parent->addChild(
                $node->getAttribute('title') ?: $node->textContent,
                ['uri' => '#' . $node->getAttribute('id')]
            );
        }

        return $menu;
    }
Get Menu

Returns a KNP Menu object, which can be traversed or rendered

@param string  $markup    Content to get items fro $this->getItems($markup, $topLevel, $depth)m
@param int     $topLevel  Top Header (1 through 6)
@param int     $depth     Depth (1 through 6)
@return ItemInterface     KNP Menu