Skip to content

Commit 2985f7f

Browse files
authored
Merge pull request #1112 from phpDocumentor/backport/1.x/pr-1104
[1.x] [FEATURE] add basic support for tables
2 parents 3f53a50 + b0b34a5 commit 2985f7f

File tree

6 files changed

+189
-21
lines changed

6 files changed

+189
-21
lines changed

packages/guides-markdown/resources/config/guides-markdown.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use phpDocumentor\Guides\Markdown\Parsers\ListItemParser;
1919
use phpDocumentor\Guides\Markdown\Parsers\ParagraphParser;
2020
use phpDocumentor\Guides\Markdown\Parsers\SeparatorParser;
21+
use phpDocumentor\Guides\Markdown\Parsers\Table\TableParser;
2122
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
2223
use Symfony\Component\String\Slugger\AsciiSlugger;
2324

@@ -58,6 +59,10 @@
5859
->tag('phpdoc.guides.markdown.parser.blockParser')
5960
->tag('phpdoc.guides.markdown.parser.subParser')
6061

62+
->set(TableParser::class)
63+
->arg('$subParsers', tagged_iterator('phpdoc.guides.markdown.parser.inlineParser'))
64+
->tag('phpdoc.guides.markdown.parser.blockParser')
65+
6166
->set(EmphasisParser::class)
6267
->arg('$inlineParsers', tagged_iterator('phpdoc.guides.markdown.parser.inlineParser'))
6368
->tag('phpdoc.guides.markdown.parser.inlineParser')

packages/guides-markdown/src/Markdown/MarkupLanguageParser.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use League\CommonMark\Environment\Environment as CommonMarkEnvironment;
1717
use League\CommonMark\Extension\Autolink\AutolinkExtension;
1818
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
19+
use League\CommonMark\Extension\Table\TableExtension;
1920
use League\CommonMark\Node\Block\Document;
2021
use League\CommonMark\Node\NodeWalker;
2122
use League\CommonMark\Parser\MarkdownParser;
@@ -46,6 +47,7 @@ public function __construct(
4647
) {
4748
$cmEnvironment = new CommonMarkEnvironment(['html_input' => 'strip']);
4849
$cmEnvironment->addExtension(new CommonMarkCoreExtension());
50+
$cmEnvironment->addExtension(new TableExtension());
4951
$cmEnvironment->addExtension(new AutolinkExtension());
5052
$this->markdownParser = new MarkdownParser($cmEnvironment);
5153
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of phpDocumentor.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*
11+
* @link https://phpdoc.org
12+
*/
13+
14+
namespace phpDocumentor\Guides\Markdown;
15+
16+
use RuntimeException;
17+
18+
class ParserException extends RuntimeException
19+
{
20+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of phpDocumentor.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*
11+
* @link https://phpdoc.org
12+
*/
13+
14+
namespace phpDocumentor\Guides\Markdown\Parsers\Table;
15+
16+
use League\CommonMark\Extension\Table\Table as CommonMarkTable;
17+
use League\CommonMark\Extension\Table\TableCell;
18+
use League\CommonMark\Extension\Table\TableRow as CommonMarkTableRow;
19+
use League\CommonMark\Extension\Table\TableSection;
20+
use League\CommonMark\Node\Node as CommonMarkNode;
21+
use League\CommonMark\Node\NodeWalker;
22+
use League\CommonMark\Node\NodeWalkerEvent;
23+
use phpDocumentor\Guides\Markdown\ParserException;
24+
use phpDocumentor\Guides\Markdown\Parsers\AbstractBlockParser;
25+
use phpDocumentor\Guides\MarkupLanguageParser as GuidesParser;
26+
use phpDocumentor\Guides\Nodes\Node;
27+
use phpDocumentor\Guides\Nodes\Table\TableColumn;
28+
use phpDocumentor\Guides\Nodes\Table\TableRow;
29+
use phpDocumentor\Guides\Nodes\TableNode;
30+
use Psr\Log\LoggerInterface;
31+
32+
use function sprintf;
33+
34+
/** @extends AbstractBlockParser<TableNode> */
35+
final class TableParser extends AbstractBlockParser
36+
{
37+
/** @param iterable<AbstractBlockParser<Node>> $subParsers */
38+
public function __construct(
39+
private readonly iterable $subParsers,
40+
private readonly LoggerInterface $logger,
41+
) {
42+
}
43+
44+
public function parse(GuidesParser $parser, NodeWalker $walker, CommonMarkNode $current): TableNode
45+
{
46+
$headerRows = [];
47+
$bodyRows = [];
48+
49+
while ($event = $walker->next()) {
50+
$commonMarkNode = $event->getNode();
51+
52+
if ($event->isEntering()) {
53+
if ($commonMarkNode instanceof TableSection) {
54+
if ($commonMarkNode->isHead()) {
55+
$headerRows = $this->parseTableSection($parser, $walker);
56+
continue;
57+
}
58+
59+
$bodyRows = $this->parseTableSection($parser, $walker);
60+
}
61+
62+
continue;
63+
}
64+
65+
if ($commonMarkNode instanceof CommonMarkTable) {
66+
return new TableNode($bodyRows, $headerRows);
67+
}
68+
69+
$this->logger->warning(sprintf('"%s" node is not yet supported in context %s. ', $commonMarkNode::class, 'Header'));
70+
}
71+
72+
throw new ParserException('Unexpected end of NodeWalker');
73+
}
74+
75+
public function supports(NodeWalkerEvent $event): bool
76+
{
77+
return $event->isEntering() && $event->getNode() instanceof CommonMarkTable;
78+
}
79+
80+
/** @return TableRow[] */
81+
private function parseTableSection(GuidesParser $parser, NodeWalker $walker): array
82+
{
83+
$rows = [];
84+
while ($event = $walker->next()) {
85+
if ($event->isEntering()) {
86+
$rows[] = $this->parseRow($parser, $walker);
87+
continue;
88+
}
89+
90+
if ($event->getNode() instanceof TableSection) {
91+
return $rows;
92+
}
93+
94+
$this->logger->warning(sprintf('"%s" node is not yet supported in context %s. ', $event->getNode()::class, 'Table section'));
95+
}
96+
97+
throw new ParserException('Unexpected end of NodeWalker');
98+
}
99+
100+
private function parseRow(GuidesParser $parser, NodeWalker $walker): TableRow
101+
{
102+
$cells = [];
103+
while ($event = $walker->next()) {
104+
if ($event->isEntering()) {
105+
$cells[] = $this->parseCell($parser, $walker);
106+
continue;
107+
}
108+
109+
if ($event->getNode() instanceof CommonMarkTableRow) {
110+
return new TableRow($cells);
111+
}
112+
113+
$this->logger->warning(sprintf('"%s" node is not yet supported in context %s. ', $event->getNode()::class, 'Table row'));
114+
}
115+
116+
throw new ParserException('Unexpected end of NodeWalker');
117+
}
118+
119+
private function parseCell(GuidesParser $parser, NodeWalker $walker): TableColumn
120+
{
121+
$nodes = [];
122+
while ($event = $walker->next()) {
123+
if ($event->isEntering()) {
124+
foreach ($this->subParsers as $subParser) {
125+
if ($subParser->supports($event)) {
126+
$nodes[] = $subParser->parse($parser, $walker, $event->getNode());
127+
break;
128+
}
129+
}
130+
131+
continue;
132+
}
133+
134+
if ($event->getNode() instanceof TableCell) {
135+
return new TableColumn('', 1, $nodes, 1);
136+
}
137+
138+
$this->logger->warning(sprintf('"%s" node is not yet supported in context %s. ', $event->getNode()::class, 'Table Cell'));
139+
}
140+
141+
throw new ParserException('Unexpected end of NodeWalker');
142+
}
143+
}
Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,31 @@
11
<!-- content start -->
2-
<div class="section" id="table-markdown">
3-
<h1>Table Markdown</h1>
4-
5-
<table>
6-
<thead>
7-
<tr>
8-
<th>Name</th>
9-
<th>Age</th>
10-
<th>City</th>
11-
</tr>
2+
<div class="section" id="table-markdown">
3+
<h1>Table Markdown</h1>
4+
<table>
5+
<thead>
6+
<tr>
7+
<th>Name</th>
8+
<th>Age</th>
9+
<th>City</th>
10+
</tr>
1211
</thead>
13-
<tbody>
14-
<tr>
12+
<tbody>
13+
<tr>
1514
<td>John Doe</td>
1615
<td>29</td>
1716
<td>New York</td>
18-
</tr>
19-
<tr>
17+
</tr>
18+
<tr>
2019
<td>Jane Smith</td>
2120
<td>34</td>
2221
<td>San Francisco</td>
23-
</tr>
24-
<tr>
22+
</tr>
23+
<tr>
2524
<td>Sam Green</td>
2625
<td>22</td>
2726
<td>Boston</td>
28-
</tr>
29-
</tbody>
30-
</table>
31-
</div>
27+
</tr>
28+
</tbody>
29+
</table>
30+
</div>
3231
<!-- content end -->

tests/Integration/tests/markdown/table-md/input/skip

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)