<?php /** * @copyright Copyright 2023 Daniel Pimley * @license https://github.com/xenocrat/chyrp-markdown/blob/master/LICENSE * @link https://github.com/xenocrat/chyrp-markdown#readme */ namespace xenocrat\markdown\block; /** * Adds figure/figcaption blocks. */ trait FigureTrait { /** * Identify a line as the beginning of a figure. */ protected function identifyFigure($line): bool { if ( $line[0] === ' ' && strspn($line, ' ') < 4 ) { // Trim up to three spaces. $line = ltrim($line, ' '); } return $line[0] === ':'; } /** * Consume lines for a figure. */ protected function consumeFigure($lines, $current): array { $content = []; $caption = []; // Consume until end of markers... for ($i = $current, $count = count($lines); $i < $count; $i++) { $line = $lines[$i]; if ( isset($line[0]) && $line[0] === ' ' && strspn($line, ' ') < 4 ) { // Trim up to three spaces. $line = ltrim($line, ' '); } if (ltrim($line) !== '') { if (str_starts_with($line, ':: ')) { $caption[$i] = substr($line, 3); continue; } elseif (str_starts_with($line, '::')) { $caption[$i] = substr($line, 2); continue; } elseif (str_starts_with($line, ': ')) { $content[] = substr($line, 2); } elseif (str_starts_with($line, ':')) { $content[] = substr($line, 1); } else { --$i; break; } } else { break; } } // Decide caption placement and remove invalid lines. if (isset($caption[$current])) { $endcap = false; for ($x = $current; $x < $i; $x++) { if ($x !== $current && !isset($caption[$x - 1])) { unset($caption[$x]); } } } elseif (isset($caption[$i - 1])) { $endcap = true; for ($x = $i - 1; $x >= $current; $x--) { if ($x !== $i - 1 && !isset($caption[$x + 1])) { unset($caption[$x]); } } } else { $endcap = null; $caption = []; } $block = [ 'figure', 'endcap' => $endcap, 'content' => $this->parseBlocks($content), 'caption' => $this->parseBlocks(array_values($caption)), ]; return [$block, $i]; } /** * Renders a figure. */ protected function renderFigure($block): string { $caption = $block['endcap'] === null ? '' : "<figcaption>\n" . $this->renderAbsy($block['caption']) . "</figcaption>\n" ; if ($block['endcap'] === false) { $figure = "<figure>\n" . $caption . $this->renderAbsy($block['content']) . "</figure>\n"; } else { $figure = "<figure>\n" . $this->renderAbsy($block['content']) . $caption . "</figure>\n"; } return $figure; } abstract protected function parseBlocks($lines); abstract protected function renderAbsy($absy); }