1<?php 2 3/* 4 * This file is part of the league/commonmark package. 5 * 6 * (c) Colin O'Dell <colinodell@gmail.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace League\CommonMark\Extension\TableOfContents\Normalizer; 13 14use League\CommonMark\Block\Element\ListBlock; 15use League\CommonMark\Block\Element\ListItem; 16use League\CommonMark\Extension\TableOfContents\Node\TableOfContents; 17 18final class RelativeNormalizerStrategy implements NormalizerStrategyInterface 19{ 20 /** @var TableOfContents */ 21 private $toc; 22 23 /** @var array<int, ListItem> */ 24 private $listItemStack = []; 25 26 public function __construct(TableOfContents $toc) 27 { 28 $this->toc = $toc; 29 } 30 31 public function addItem(int $level, ListItem $listItemToAdd): void 32 { 33 \end($this->listItemStack); 34 $previousLevel = \key($this->listItemStack); 35 36 // Pop the stack if we're too deep 37 while ($previousLevel !== null && $level < $previousLevel) { 38 array_pop($this->listItemStack); 39 \end($this->listItemStack); 40 $previousLevel = \key($this->listItemStack); 41 } 42 43 /** @var ListItem|false $lastListItem */ 44 $lastListItem = \current($this->listItemStack); 45 46 // Need to go one level deeper? Add that level 47 if ($lastListItem !== false && $level > $previousLevel) { 48 $targetListBlock = new ListBlock($lastListItem->getListData()); 49 $targetListBlock->setStartLine($listItemToAdd->getStartLine()); 50 $targetListBlock->setEndLine($listItemToAdd->getEndLine()); 51 $lastListItem->appendChild($targetListBlock); 52 // Otherwise we're at the right level 53 // If there's no stack we're adding this item directly to the TOC element 54 } elseif ($lastListItem === false) { 55 $targetListBlock = $this->toc; 56 // Otherwise add it to the last list item 57 } else { 58 $targetListBlock = $lastListItem->parent(); 59 } 60 61 $targetListBlock->appendChild($listItemToAdd); 62 $this->listItemStack[$level] = $listItemToAdd; 63 } 64} 65 66// Trigger autoload without causing a deprecated error 67\class_exists(TableOfContents::class); 68