leilukin-tumbleblog/includes/lib/xenocrat/markdown/block/FigureTrait.php

127 lines
2.7 KiB
PHP

<?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);
}