-
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The newly added iterators do iterate the toc tree to find the order of rendering of documents. This is required to have single page outputs in the correct order. The downside of this new approach is that only documents that are in a toc-tree are rendered.
- Loading branch information
Showing
13 changed files
with
474 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace phpDocumentor\Guides\Renderer; | ||
|
||
use AppendIterator; | ||
use Generator; | ||
use Iterator; | ||
use phpDocumentor\Guides\Nodes\DocumentNode; | ||
use RecursiveIteratorIterator; | ||
use WeakMap; | ||
use WeakReference; | ||
|
||
/** @implements Iterator<array-key, DocumentNode> */ | ||
final class DocumentListIterator implements Iterator | ||
{ | ||
/** @var WeakReference<DocumentNode>|null */ | ||
private WeakReference|null $previousDocument; | ||
|
||
/** @var WeakReference<DocumentNode>|null */ | ||
private WeakReference|null $nextDocument; | ||
|
||
/** @var WeakMap<DocumentNode, bool> */ | ||
private WeakMap $unseenDocuments; | ||
|
||
/** @var Iterator<array-key, DocumentNode> */ | ||
private Iterator $innerIterator; | ||
|
||
/** @param DocumentNode[] $documents */ | ||
public function __construct( | ||
DocumentTreeIterator $iterator, | ||
array $documents, | ||
) { | ||
$this->unseenDocuments = new WeakMap(); | ||
$this->previousDocument = null; | ||
$this->nextDocument = null; | ||
$this->innerIterator = new AppendIterator(); | ||
$this->innerIterator->append( | ||
new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST), | ||
); | ||
$this->innerIterator->append($this->unseenIterator()); | ||
foreach ($documents as $document) { | ||
$this->unseenDocuments[$document] = true; | ||
} | ||
} | ||
|
||
public function next(): void | ||
{ | ||
if ($this->innerIterator->valid()) { | ||
$this->previousDocument = WeakReference::create($this->current()); | ||
} else { | ||
$this->previousDocument = null; | ||
} | ||
|
||
if ($this->nextDocument === null) { | ||
$this->innerIterator->next(); | ||
} | ||
|
||
$this->nextDocument = null; | ||
} | ||
|
||
public function previousNode(): DocumentNode|null | ||
{ | ||
return $this->previousDocument?->get(); | ||
} | ||
|
||
public function valid(): bool | ||
{ | ||
if ($this->nextDocument !== null) { | ||
return true; | ||
} | ||
|
||
return $this->innerIterator->valid(); | ||
} | ||
|
||
public function nextNode(): DocumentNode|null | ||
{ | ||
$this->innerIterator->next(); | ||
|
||
if ($this->innerIterator->valid()) { | ||
$this->nextDocument = WeakReference::create($this->current()); | ||
} | ||
|
||
return $this->nextDocument?->get(); | ||
} | ||
|
||
public function current(): mixed | ||
{ | ||
$document = $this->innerIterator->current(); | ||
if ($document instanceof DocumentNode) { | ||
$this->unseenDocuments[$document] = false; | ||
} | ||
|
||
return $document; | ||
} | ||
|
||
public function key(): mixed | ||
{ | ||
return $this->innerIterator->key(); | ||
} | ||
|
||
public function rewind(): void | ||
{ | ||
foreach ($this->unseenDocuments as $document => $seen) { | ||
$this->unseenDocuments[$document] = true; | ||
} | ||
|
||
$this->innerIterator->rewind(); | ||
} | ||
|
||
/** @return Generator<DocumentNode> */ | ||
private function unseenIterator(): Generator | ||
{ | ||
foreach ($this->unseenDocuments as $document => $seen) { | ||
if ($seen === false) { | ||
continue; | ||
} | ||
|
||
yield $document; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace phpDocumentor\Guides\Renderer; | ||
|
||
use LogicException; | ||
use phpDocumentor\Guides\Nodes\DocumentNode; | ||
use phpDocumentor\Guides\Nodes\DocumentTree\DocumentEntryNode; | ||
use RecursiveIterator; | ||
|
||
/** | ||
* Iterates over the document tree and returns the documents in the table of contents order. | ||
* | ||
* @internal This class is not part of the public API of this package and should not be used outside of this package. | ||
* | ||
* @implements RecursiveIterator<int, DocumentNode> | ||
*/ | ||
final class DocumentTreeIterator implements RecursiveIterator | ||
{ | ||
private int $position = 0; | ||
|
||
/** | ||
* @param DocumentEntryNode[] $levelNodes | ||
* @param DocumentNode[] $documents | ||
*/ | ||
public function __construct( | ||
private readonly array $levelNodes, | ||
private readonly array $documents, | ||
) { | ||
} | ||
|
||
public function current(): DocumentNode | ||
{ | ||
foreach ($this->documents as $document) { | ||
if ($document->getDocumentEntry() === $this->levelNodes[$this->position]) { | ||
return $document; | ||
} | ||
} | ||
|
||
throw new LogicException('Could not find document for node'); | ||
} | ||
|
||
public function next(): void | ||
{ | ||
++$this->position; | ||
} | ||
|
||
public function key(): int | ||
{ | ||
return $this->position; | ||
} | ||
|
||
public function valid(): bool | ||
{ | ||
return isset($this->levelNodes[$this->position]); | ||
} | ||
|
||
public function rewind(): void | ||
{ | ||
$this->position = 0; | ||
} | ||
|
||
public function hasChildren(): bool | ||
{ | ||
return empty($this->levelNodes[$this->position]->getChildren()) === false; | ||
} | ||
|
||
public function getChildren(): self|null | ||
{ | ||
return new self($this->levelNodes[$this->position]->getChildren(), $this->documents); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.