Skip to content

Commit 9cb5d18

Browse files
Use a separate div wrapper
1 parent 1a715b4 commit 9cb5d18

File tree

8 files changed

+140
-21
lines changed

8 files changed

+140
-21
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the league/commonmark package.
7+
*
8+
* (c) Colin O'Dell <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace League\CommonMark\Extension\TableOfContents\Node;
15+
16+
use League\CommonMark\Node\Block\AbstractBlock;
17+
18+
final class TableOfContentsWrapper extends AbstractBlock
19+
{
20+
public function getInnerToc(): TableOfContents
21+
{
22+
$children = $this->children();
23+
if (count($children) != 2) {
24+
throw new InvalidArgumentException(
25+
'TableOfContentsWrapper nodes should have 2 children, found ' . count($children)
26+
);
27+
}
28+
$inner = $children[1];
29+
if (! $inner instanceof TableOfContents) {
30+
throw new InvalidArgumentException(
31+
'TableOfContentsWrapper second node should be a TableOfContents, found ' . get_class($inner)
32+
);
33+
}
34+
return $inner;
35+
}
36+
}

src/Extension/TableOfContents/TableOfContentsBuilder.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use League\CommonMark\Extension\HeadingPermalink\HeadingPermalink;
1919
use League\CommonMark\Extension\TableOfContents\Node\TableOfContents;
2020
use League\CommonMark\Extension\TableOfContents\Node\TableOfContentsPlaceholder;
21+
use League\CommonMark\Extension\TableOfContents\Node\TableOfContentsWrapper;
2122
use League\CommonMark\Node\Block\Document;
2223
use League\CommonMark\Node\NodeIterator;
2324
use League\Config\ConfigurationAwareInterface;
@@ -55,7 +56,11 @@ public function onDocumentParsed(DocumentParsedEvent $event): void
5556
// Add custom CSS class(es), if defined
5657
$class = $this->config->get('table_of_contents/html_class');
5758
if ($class !== null) {
58-
$toc->data->append('attributes/class', $class);
59+
if ($toc instanceof TableOfContentsWrapper) {
60+
$toc->getInnerToc()->data->append('attributes/class', $class);
61+
} else {
62+
$toc->data->append('attributes/class', $class);
63+
}
5964
}
6065

6166
// Add the TOC to the Document

src/Extension/TableOfContents/TableOfContentsExtension.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use League\CommonMark\Extension\ConfigurableExtensionInterface;
2121
use League\CommonMark\Extension\TableOfContents\Node\TableOfContents;
2222
use League\CommonMark\Extension\TableOfContents\Node\TableOfContentsPlaceholder;
23+
use League\CommonMark\Extension\TableOfContents\Node\TableOfContentsWrapper;
2324
use League\Config\ConfigurationBuilderInterface;
2425
use Nette\Schema\Expect;
2526

@@ -42,6 +43,7 @@ public function configureSchema(ConfigurationBuilderInterface $builder): void
4243
public function register(EnvironmentBuilderInterface $environment): void
4344
{
4445
$environment->addRenderer(TableOfContents::class, new TableOfContentsRenderer(new ListBlockRenderer()));
46+
$environment->addRenderer(TableOfContentsWrapper::class, new TableOfContentsWrapperRenderer);
4547
$environment->addEventListener(DocumentParsedEvent::class, [new TableOfContentsBuilder(), 'onDocumentParsed'], -150);
4648

4749
// phpcs:ignore SlevomatCodingStandard.ControlStructures.EarlyExit.EarlyExitNotUsed

src/Extension/TableOfContents/TableOfContentsGenerator.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@
2121
use League\CommonMark\Extension\CommonMark\Node\Inline\Strong;
2222
use League\CommonMark\Extension\HeadingPermalink\HeadingPermalink;
2323
use League\CommonMark\Extension\TableOfContents\Node\TableOfContents;
24+
use League\CommonMark\Extension\TableOfContents\Node\TableOfContentsWrapper;
2425
use League\CommonMark\Extension\TableOfContents\Normalizer\AsIsNormalizerStrategy;
2526
use League\CommonMark\Extension\TableOfContents\Normalizer\FlatNormalizerStrategy;
2627
use League\CommonMark\Extension\TableOfContents\Normalizer\NormalizerStrategyInterface;
2728
use League\CommonMark\Extension\TableOfContents\Normalizer\RelativeNormalizerStrategy;
29+
use League\CommonMark\Node\Block\AbstractBlock;
2830
use League\CommonMark\Node\Block\Document;
2931
use League\CommonMark\Node\Inline\Text;
3032
use League\CommonMark\Node\NodeIterator;
@@ -73,7 +75,11 @@ public function __construct(string $style, string $normalizationStrategy, int $m
7375
}
7476
}
7577

76-
public function generate(Document $document): ?TableOfContents
78+
/**
79+
* If there is a table of contents, returns either a `TableOfContents` or
80+
* `TableOfContentsWrapper` node object
81+
*/
82+
public function generate(Document $document): ?AbstractBlock
7783
{
7884
$toc = $this->createToc($document);
7985

@@ -120,7 +126,12 @@ public function generate(Document $document): ?TableOfContents
120126
if ($this->label !== '') {
121127
$label = new Strong();
122128
$label->appendChild(new Text($this->label));
123-
$toc->prependChild($label);
129+
$wrapper = new TableOfContentsWrapper();
130+
$wrapper->appendChild($label);
131+
$wrapper->appendChild($toc);
132+
$wrapper->setStartLine($toc->getStartLine());
133+
$wrapper->setEndLine($toc->getEndLine());
134+
return $wrapper;
124135
}
125136

126137
return $toc;

src/Extension/TableOfContents/TableOfContentsGeneratorInterface.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,14 @@
1313

1414
namespace League\CommonMark\Extension\TableOfContents;
1515

16-
use League\CommonMark\Extension\TableOfContents\Node\TableOfContents;
16+
use League\CommonMark\Node\Block\AbstractBlock;
1717
use League\CommonMark\Node\Block\Document;
1818

1919
interface TableOfContentsGeneratorInterface
2020
{
21-
public function generate(Document $document): ?TableOfContents;
21+
/**
22+
* If there is a table of contents, returns either a `TableOfContents` or
23+
* `TableOfContentsWrapper` node object.
24+
*/
25+
public function generate(Document $document): ?AbstractBlock;
2226
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the league/commonmark package.
7+
*
8+
* (c) Colin O'Dell <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace League\CommonMark\Extension\TableOfContents;
15+
16+
use InvalidArgumentException;
17+
use League\CommonMark\Extension\TableOfContents\Node\TableOfContentsWrapper;
18+
use League\CommonMark\Node\Node;
19+
use League\CommonMark\Renderer\ChildNodeRendererInterface;
20+
use League\CommonMark\Renderer\NodeRendererInterface;
21+
use League\CommonMark\Util\HtmlElement;
22+
use League\CommonMark\Xml\XmlNodeRendererInterface;
23+
24+
final class TableOfContentsWrapperRenderer implements NodeRendererInterface, XmlNodeRendererInterface
25+
{
26+
/**
27+
* {@inheritDoc}
28+
*/
29+
public function render(Node $node, ChildNodeRendererInterface $childRenderer)
30+
{
31+
TableOfContentsWrapper::assertInstanceOf($node);
32+
$children = $node->children();
33+
if (count($children) !== 2) {
34+
throw new InvalidArgumentException(
35+
'TableOfContentsWrapper nodes should have 2 children, found ' . count($children)
36+
);
37+
}
38+
$attrs = $node->data->get('attributes');
39+
40+
return new HtmlElement(
41+
'div',
42+
$attrs,
43+
$childRenderer->renderNodes($children)
44+
);
45+
}
46+
47+
public function getXmlTagName(Node $node): string
48+
{
49+
return 'table_of_contents_wrapper';
50+
}
51+
52+
/**
53+
* @return array<string, scalar>
54+
*/
55+
public function getXmlAttributes(Node $node): array
56+
{
57+
return [];
58+
}
59+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1+
<div><strong>Table of Contents</strong>
12
<ul class="table-of-contents">
2-
<strong>Table of Contents</strong>
33
<li><a href="#content-hello-world">Hello World!</a>
44
<ul>
55
<li><a href="#content-isnt-markdown-great">Isn't Markdown Great?</a></li>
66
</ul>
77
</li>
8-
</ul>
8+
</ul></div>
99
<p>This is my document.</p>
1010
<h1><a id="content-hello-world" href="#content-hello-world" class="heading-permalink" aria-hidden="true" title="Permalink"></a>Hello World!</h1>
1111
<h2><a id="content-isnt-markdown-great" href="#content-isnt-markdown-great" class="heading-permalink" aria-hidden="true" title="Permalink"></a>Isn't Markdown Great?</h2>

tests/functional/Extension/TableOfContents/xml/has-label.xml

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<document xmlns="http://commonmark.org/xml/1.0">
3-
<table_of_contents type="bullet" tight="false">
3+
<table_of_contents_wrapper>
44
<strong>
55
<text>Table of Contents</text>
66
</strong>
7-
<item>
8-
<link destination="#content-hello-world" title="">
9-
<text>Hello World!</text>
10-
</link>
11-
<list type="bullet" tight="false">
12-
<item>
13-
<link destination="#content-isnt-markdown-great" title="">
14-
<text>Isn't Markdown Great?</text>
15-
</link>
16-
</item>
17-
</list>
18-
</item>
19-
</table_of_contents>
7+
<table_of_contents type="bullet" tight="false">
8+
<item>
9+
<link destination="#content-hello-world" title="">
10+
<text>Hello World!</text>
11+
</link>
12+
<list type="bullet" tight="false">
13+
<item>
14+
<link destination="#content-isnt-markdown-great" title="">
15+
<text>Isn't Markdown Great?</text>
16+
</link>
17+
</item>
18+
</list>
19+
</item>
20+
</table_of_contents>
21+
</table_of_contents_wrapper>
2022
<paragraph>
2123
<text>This is my document.</text>
2224
</paragraph>

0 commit comments

Comments
 (0)