[], 'rows' => [], ]; // Consume until blank line... for ($i = $current, $count = count($lines); $i < $count; $i++) { $line = trim($lines[$i]); // Extract alignment from second line. if ($i == $current + 1) { $cols = explode('|', trim($line, ' |')); foreach($cols as $col) { $col = trim($col); if (empty($col)) { $block['cols'][] = ''; continue; } $l = ($col[0] === ':'); $r = str_ends_with($col, ':'); if ($l && $r) { $block['cols'][] = 'center'; } elseif ($l) { $block['cols'][] = 'left'; } elseif ($r) { $block['cols'][] = 'right'; } else { $block['cols'][] = ''; } } continue; } if ( // Blank line breaks the table. $line === '' || ( // Once iteration is beyond the header and delimiter rows, // detecting a non-paragraph block marker breaks the table. $i > $current + 1 && $this->detectLineType($lines, $i) !== 'paragraph' ) ) { break; } if ($line[0] === '|') { $line = substr($line, 1); } if ( str_ends_with($line, '|') && ( !str_ends_with($line, '\\|') || str_ends_with($line, '\\\\|') ) ) { $line = substr($line, 0, -1); } array_unshift($this->context, 'table'); $row = $this->parseInline(trim($line, ' ')); array_shift($this->context); $r = count($block['rows']); $c = 0; $block['rows'][] = []; foreach ($row as $absy) { if (!isset($block['rows'][$r][$c])) { $block['rows'][$r][] = []; } if ($absy[0] === 'tableBoundary') { $c++; } else { $block['rows'][$r][$c][] = $absy; } } } return [$block, --$i]; } /** * Render a table block. */ protected function renderTable($block): string { $head = ''; $body = ''; $cols = $block['cols']; $colCount = count($block['cols']); $first = true; foreach($block['rows'] as $row) { $cellTag = $first ? 'th' : 'td'; $tds = ''; foreach ($row as $c => $cell) { if ($c < $colCount) { $align = empty($cols[$c]) ? '' : ' align="' . $cols[$c] . '"' ; $tds .= "<$cellTag$align>" . trim($this->renderAbsy($cell)) . "$cellTag>\n"; } } for ($i = count($row); $i < $colCount; $i++) { $tds .= "<$cellTag>$cellTag$align>\n"; } if ($first) { $head .= "