Skip to content

Commit

Permalink
Merge pull request #1191 from phpDocumentor/fix/off-by-x-headings
Browse files Browse the repository at this point in the history
[FIX] make heading level dynamic
  • Loading branch information
jaapio authored Jan 10, 2025
2 parents 63b9b78 + 561af1b commit 54f9e4d
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ final class SectionCreationTransformer implements NodeTransformer
{
/** @var SectionNode[] $sectionStack */
private array $sectionStack = [];
private int $firstLevel = 1;

public function enterNode(Node $node, CompilerContextInterface $compilerContext): Node
{
if ($node instanceof DocumentNode) {
$this->firstLevel = 1;
$this->sectionStack = [];
}

Expand Down Expand Up @@ -68,7 +70,7 @@ public function leaveNode(Node $node, CompilerContextInterface $compilerContext)

if (count($this->sectionStack) > 0 && $compilerContext->getShadowTree()->isLastChildOfParent()) {
$lastSection = end($this->sectionStack);
while ($lastSection?->getTitle()->getLevel() > 1) {
while ($lastSection?->getTitle()->getLevel() > $this->firstLevel) {
$lastSection = array_pop($this->sectionStack);
}

Expand All @@ -92,17 +94,17 @@ public function leaveNode(Node $node, CompilerContextInterface $compilerContext)
end($this->sectionStack)->addChildNode($newSection);
}

$this->sectionStack[] = $newSection;
$this->pushNewSectionToStack($newSection);

return $lastSection?->getTitle()->getLevel() === 1 ? $lastSection : null;
return $lastSection?->getTitle()->getLevel() <= $this->firstLevel ? $lastSection : null;
}

$newSection = new SectionNode($node);
if ($lastSection instanceof SectionNode) {
$lastSection->addChildNode($newSection);
}

$this->sectionStack[] = $newSection;
$this->pushNewSectionToStack($newSection);

return null;
}
Expand All @@ -117,4 +119,21 @@ public function getPriority(): int
// Should run as first transformer
return PHP_INT_MAX;
}

/**
* Pushes the new section to the stack.
*
* The stack is used to track the current level of nodes and adding child
* nodes to the section. As not all documentation formats are using the
* correct level of title nodes we need to track the level of the first
* title node to determine the correct level of the section.
*/
private function pushNewSectionToStack(SectionNode $newSection): void
{
if (count($this->sectionStack) === 0) {
$this->firstLevel = $newSection->getTitle()->getLevel();
}

$this->sectionStack[] = $newSection;
}
}
2 changes: 1 addition & 1 deletion packages/guides/src/Nodes/DocumentNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public function getPageTitle(): string|null
public function getTitle(): TitleNode|null
{
foreach ($this->value as $node) {
if ($node instanceof SectionNode && $node->getTitle()->getLevel() === 1) {
if ($node instanceof SectionNode) {
return $node->getTitle();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!-- content start -->

<div class="section" id="introduction">
<h2>Introduction</h2>

<p>This is a sample Markdown document demonstrating sections and subsections.</p>

</div>
<div class="section" id="section-1">
<h2>Section 1</h2>

<p>This is the first section of the document.</p>

<div class="section" id="subsection-1-1">
<h3>Subsection 1.1</h3>

<p>This is a subsection under Section 1.</p>

</div>
<div class="section" id="subsection-1-2">
<h3>Subsection 1.2</h3>

<p>Another subsection under Section 1.</p>

</div>
</div>
<div class="section" id="section-2">
<h2>Section 2</h2>

<p>Moving on to the second section of the document.</p>

<div class="section" id="subsection-2-1">
<h3>Subsection 2.1</h3>

<p>A subsection under Section 2.</p>

</div>
</div>
<div class="section" id="conclusion">
<h2>Conclusion</h2>

<p>In conclusion, this is a simple example of a Markdown document with various sections and subsections.</p>

</div>
<!-- content end -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<guides xmlns="https://www.phpdoc.org/guides"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.phpdoc.org/guides packages/guides-cli/resources/schema/guides.xsd"
input-format="md"
>
</guides>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## Introduction

This is a sample Markdown document demonstrating sections and subsections.

## Section 1

This is the first section of the document.

### Subsection 1.1

This is a subsection under Section 1.

### Subsection 1.2

Another subsection under Section 1.

## Section 2

Moving on to the second section of the document.

### Subsection 2.1

A subsection under Section 2.

## Conclusion

In conclusion, this is a simple example of a Markdown document with various sections and subsections.

0 comments on commit 54f9e4d

Please sign in to comment.