1<?php 2 3declare(strict_types=1); 4 5/* 6 * This file is part of the league/commonmark package. 7 * 8 * (c) Colin O'Dell <colinodell@gmail.com> 9 * 10 * For the full copyright and license information, please view the LICENSE 11 * file that was distributed with this source code. 12 */ 13 14namespace League\CommonMark\Node; 15 16use League\CommonMark\Node\Block\AbstractBlock; 17 18/** 19 * @implements \IteratorAggregate<int, Node> 20 */ 21final class NodeIterator implements \IteratorAggregate 22{ 23 public const FLAG_BLOCKS_ONLY = 1; 24 25 private Node $node; 26 private bool $blocksOnly; 27 28 public function __construct(Node $node, int $flags = 0) 29 { 30 $this->node = $node; 31 $this->blocksOnly = ($flags & self::FLAG_BLOCKS_ONLY) === self::FLAG_BLOCKS_ONLY; 32 } 33 34 /** 35 * @return \Generator<int, Node> 36 */ 37 public function getIterator(): \Generator 38 { 39 $stack = [$this->node]; 40 $index = 0; 41 42 while ($stack) { 43 $node = \array_pop($stack); 44 45 yield $index++ => $node; 46 47 // Push all children onto the stack in reverse order 48 $child = $node->lastChild(); 49 while ($child !== null) { 50 if (! $this->blocksOnly || $child instanceof AbstractBlock) { 51 $stack[] = $child; 52 } 53 54 $child = $child->previous(); 55 } 56 } 57 } 58} 59