diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f947f67ff..a3ed982727 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Updates should follow the [Keep a CHANGELOG](https://keepachangelog.com/) princi - `heading_permalink/apply_id_to_heading` - When `true`, the `id` attribute will be applied to the heading element itself instead of the `` tag - `heading_permalink/heading_class` - class to apply to the heading element - `heading_permalink/insert` - now accepts `none` to prevent the creation of the `` link +- Added new `table/alignment_attributes` configuration option to control how table cell alignment is rendered (#959) ### Changed diff --git a/docs/2.4/extensions/tables.md b/docs/2.4/extensions/tables.md index ef42d05007..a0a4923d57 100644 --- a/docs/2.4/extensions/tables.md +++ b/docs/2.4/extensions/tables.md @@ -39,6 +39,11 @@ $config = [ 'tag' => 'div', 'attributes' => [], ], + 'alignment_attributes' => [ + 'left' => ['align' => 'left'], + 'center' => ['align' => 'center'], + 'right' => ['align' => 'right'], + ], ], ]; @@ -122,6 +127,38 @@ $config = [ ]; ``` +### Alignment + +You can configure the HTML attributes used for alignment via the `alignment_attributes` option. For example, if you wanted Bootstrap classes to be applied, you could do so like this: + +```php +$config = [ + 'table' => [ + 'alignment_attributes' => [ + 'left' => ['class' => 'text-start'], + 'center' => ['class' => 'text-center'], + 'right' => ['class' => 'text-end'], + ], + ], +]; +``` + +Or you could use inline styles: + +```php +$config = [ + 'table' => [ + 'alignment_attributes' => [ + 'left' => ['style' => 'text-align:left'], + 'center' => ['style' => 'text-align:center'], + 'right' => ['style' => 'text-align:right'], + ], + ], +]; +``` + +Or any other HTML attributes you'd like! + ## Credits The Table functionality was originally built by [Martin HasoĊˆ](https://github.com/hason) and [Webuni s.r.o.](https://www.webuni.cz) before it was merged into the core parser. diff --git a/src/Extension/Table/TableCellRenderer.php b/src/Extension/Table/TableCellRenderer.php index e6b736a3b7..99512c3c43 100644 --- a/src/Extension/Table/TableCellRenderer.php +++ b/src/Extension/Table/TableCellRenderer.php @@ -15,6 +15,7 @@ namespace League\CommonMark\Extension\Table; +use League\CommonMark\Extension\Attributes\Util\AttributesHelper; use League\CommonMark\Node\Node; use League\CommonMark\Renderer\ChildNodeRendererInterface; use League\CommonMark\Renderer\NodeRendererInterface; @@ -23,6 +24,23 @@ final class TableCellRenderer implements NodeRendererInterface, XmlNodeRendererInterface { + private const DEFAULT_ATTRIBUTES = [ + TableCell::ALIGN_LEFT => ['align' => 'left'], + TableCell::ALIGN_CENTER => ['align' => 'center'], + TableCell::ALIGN_RIGHT => ['align' => 'right'], + ]; + + /** @var array> */ + private array $alignmentAttributes; + + /** + * @param array> $alignmentAttributes + */ + public function __construct(array $alignmentAttributes = self::DEFAULT_ATTRIBUTES) + { + $this->alignmentAttributes = $alignmentAttributes; + } + /** * @param TableCell $node * @@ -35,9 +53,8 @@ public function render(Node $node, ChildNodeRendererInterface $childRenderer): \ TableCell::assertInstanceOf($node); $attrs = $node->data->get('attributes'); - - if ($node->getAlign() !== null) { - $attrs['align'] = $node->getAlign(); + if (($alignment = $node->getAlign()) !== null) { + $attrs = AttributesHelper::mergeAttributes($attrs, $this->alignmentAttributes[$alignment]); } $tag = $node->getType() === TableCell::TYPE_HEADER ? 'th' : 'td'; diff --git a/src/Extension/Table/TableExtension.php b/src/Extension/Table/TableExtension.php index 2e4f232400..8cc09acc6c 100644 --- a/src/Extension/Table/TableExtension.php +++ b/src/Extension/Table/TableExtension.php @@ -25,12 +25,22 @@ final class TableExtension implements ConfigurableExtensionInterface { public function configureSchema(ConfigurationBuilderInterface $builder): void { + $attributeArraySchema = Expect::arrayOf( + Expect::type('string|string[]|bool'), // attribute value(s) + 'string' // attribute name + ); + $builder->addSchema('table', Expect::structure([ 'wrap' => Expect::structure([ 'enabled' => Expect::bool()->default(false), 'tag' => Expect::string()->default('div'), 'attributes' => Expect::arrayOf(Expect::string()), ]), + 'alignment_attributes' => Expect::structure([ + 'left' => (clone $attributeArraySchema)->default(['align' => 'left']), + 'center' => (clone $attributeArraySchema)->default(['align' => 'center']), + 'right' => (clone $attributeArraySchema)->default(['align' => 'right']), + ]), ])); } @@ -47,6 +57,6 @@ public function register(EnvironmentBuilderInterface $environment): void ->addRenderer(Table::class, $tableRenderer) ->addRenderer(TableSection::class, new TableSectionRenderer()) ->addRenderer(TableRow::class, new TableRowRenderer()) - ->addRenderer(TableCell::class, new TableCellRenderer()); + ->addRenderer(TableCell::class, new TableCellRenderer($environment->getConfiguration()->get('table/alignment_attributes'))); } } diff --git a/tests/unit/Extension/Table/TableCellRendererTest.php b/tests/unit/Extension/Table/TableCellRendererTest.php index c342b26d3d..9448b97a63 100644 --- a/tests/unit/Extension/Table/TableCellRendererTest.php +++ b/tests/unit/Extension/Table/TableCellRendererTest.php @@ -61,6 +61,23 @@ public function testRenderWithTableCellHavingAlignment(): void $this->assertSame('::children::', (string) $renderer->render($tableCell, $childRenderer)); } + public function testRenderWithTableCellWithCustomAttributes(): void + { + $tableCell = new TableCell(TableCell::TYPE_DATA, TableCell::ALIGN_CENTER); + $tableCell->data->set('attributes/class', 'foo'); + + $childRenderer = new FakeChildNodeRenderer(); + $childRenderer->pretendChildrenExist(); + + $renderer = new TableCellRenderer([ + 'left' => ['class' => 'foo', 'style' => 'text-align: left'], + 'center' => ['class' => 'bar', 'style' => 'text-align: center'], + 'right' => ['class' => 'baz', 'style' => 'text-align: right'], + ]); + + $this->assertSame('::children::', (string) $renderer->render($tableCell, $childRenderer)); + } + public function testRenderWithWrongType(): void { $this->expectException(InvalidArgumentException::class);