1<?php
2
3declare(strict_types=1);
4
5/*
6 * This is part of the league/commonmark package.
7 *
8 * (c) Martin Hasoň <martin.hason@gmail.com>
9 * (c) Webuni s.r.o. <info@webuni.cz>
10 * (c) Colin O'Dell <colinodell@gmail.com>
11 *
12 * For the full copyright and license information, please view the LICENSE
13 * file that was distributed with this source code.
14 */
15
16namespace League\CommonMark\Extension\Table;
17
18use League\CommonMark\Extension\Attributes\Util\AttributesHelper;
19use League\CommonMark\Node\Node;
20use League\CommonMark\Renderer\ChildNodeRendererInterface;
21use League\CommonMark\Renderer\NodeRendererInterface;
22use League\CommonMark\Util\HtmlElement;
23use League\CommonMark\Xml\XmlNodeRendererInterface;
24
25final class TableCellRenderer implements NodeRendererInterface, XmlNodeRendererInterface
26{
27    private const DEFAULT_ATTRIBUTES = [
28        TableCell::ALIGN_LEFT   => ['align' => 'left'],
29        TableCell::ALIGN_CENTER => ['align' => 'center'],
30        TableCell::ALIGN_RIGHT  => ['align' => 'right'],
31    ];
32
33    /** @var array<TableCell::ALIGN_*, array<string, string|string[]|bool>> */
34    private array $alignmentAttributes;
35
36    /**
37     * @param array<TableCell::ALIGN_*, array<string, string|string[]|bool>> $alignmentAttributes
38     */
39    public function __construct(array $alignmentAttributes = self::DEFAULT_ATTRIBUTES)
40    {
41        $this->alignmentAttributes = $alignmentAttributes;
42    }
43
44    /**
45     * @param TableCell $node
46     *
47     * {@inheritDoc}
48     *
49     * @psalm-suppress MoreSpecificImplementedParamType
50     */
51    public function render(Node $node, ChildNodeRendererInterface $childRenderer): \Stringable
52    {
53        TableCell::assertInstanceOf($node);
54
55        $attrs = $node->data->get('attributes');
56        if (($alignment = $node->getAlign()) !== null) {
57            $attrs = AttributesHelper::mergeAttributes($attrs, $this->alignmentAttributes[$alignment]);
58        }
59
60        $tag = $node->getType() === TableCell::TYPE_HEADER ? 'th' : 'td';
61
62        return new HtmlElement($tag, $attrs, $childRenderer->renderNodes($node->children()));
63    }
64
65    public function getXmlTagName(Node $node): string
66    {
67        return 'table_cell';
68    }
69
70    /**
71     * @param TableCell $node
72     *
73     * @return array<string, scalar>
74     *
75     * @psalm-suppress MoreSpecificImplementedParamType
76     */
77    public function getXmlAttributes(Node $node): array
78    {
79        TableCell::assertInstanceOf($node);
80
81        $ret = ['type' => $node->getType()];
82
83        if (($align = $node->getAlign()) !== null) {
84            $ret['align'] = $align;
85        }
86
87        return $ret;
88    }
89}
90