config = $config; } /** @var array */ private static $alignments = [ 'left' => ':--', 'right' => '--:', 'center' => ':-:', ]; /** @var array|null */ private $columnAlignments = []; /** @var string|null */ private $caption = null; public function preConvert(ElementInterface $element): void { $tag = $element->getTagName(); // Only table cells and caption are allowed to contain content. // Remove all text between other table elements. if ($tag === 'th' || $tag === 'td' || $tag === 'caption') { return; } foreach ($element->getChildren() as $child) { if ($child->isText()) { $child->setFinalMarkdown(''); } } } public function convert(ElementInterface $element): string { $value = $element->getValue(); switch ($element->getTagName()) { case 'table': $this->columnAlignments = []; if ($this->caption) { $side = $this->config->getOption('table_caption_side'); // Kept apart from the rows, since it can contain a block of HTML which would take them in if ($side === 'top') { $value = $this->caption . "\n\n" . $value; } elseif ($side === 'bottom') { $value .= "\n" . $this->caption . "\n"; } $this->caption = null; } return $value . "\n"; case 'caption': // A leading no-break space is kept, as whatever follows it wasn't escaped as being at the start of the line $this->caption = \ltrim(NoBreakSpaces::rtrim($value)); return ''; case 'tr': $value .= "|\n"; if ($this->columnAlignments !== null) { $value .= '|' . \implode('|', $this->columnAlignments) . "|\n"; $this->columnAlignments = null; } return $value; case 'th': case 'td': if ($this->columnAlignments !== null) { $align = $element->getAttribute('align'); $this->columnAlignments[] = self::$alignments[$align] ?? '---'; } $value = \str_replace("\n", ' ', $value); $escape = Coerce::toString($this->config->getOption('table_pipe_escape') ?? '\|'); $value = \preg_replace_callback('/(?