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

86 lines
1.8 KiB
PHP
Raw Permalink Normal View History

2024-09-05 17:51:48 +00:00
<?php
/**
* @copyright Copyright 2024 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 math expression (LaTeX) blocks.
*/
trait MathTrait
{
/**
* Identify a line as the beginning of a math expression.
*/
protected function identifyMath($line): bool
{
if (
$line[0] === ' '
&& strspn($line, ' ') < 4
) {
// trim up to three spaces
$line = ltrim($line, ' ');
}
return str_starts_with($line, '$$');
}
/**
* Consume lines for a math expression.
*/
protected function consumeMath($lines, $current): array
{
$indent = strspn($lines[$current], ' ');
$line = substr($lines[$current], $indent);
$mw = strspn($line, $line[0]);
$fence = substr($line, 0, $mw);
$content = [];
// Consume until end fence...
for ($i = $current + 1, $count = count($lines); $i < $count; $i++) {
$line = $lines[$i];
$leadingSpaces = strspn($line, ' ');
if (
$leadingSpaces > 3
|| strspn(ltrim($line), $fence[0]) < $mw
|| !str_ends_with(rtrim($line), $fence[0])
) {
if ($indent > 0 && $leadingSpaces > 0) {
if ($leadingSpaces < $indent) {
$line = ltrim($line);
} else {
$line = substr($line, $indent);
}
}
$content[] = $line;
} else {
break;
}
}
$block = [
'math',
'content' => implode("\n", $content),
];
return [$block, $i];
}
/**
* Renders a math expression.
*/
protected function renderMath($block): string
{
return '<la-tex display="block">'
. $this->escapeHtmlEntities(
$block['content'],
ENT_COMPAT | ENT_SUBSTITUTE
)
. ($block['content'] === '' ? '' : "\n" )
. "</la-tex>\n";
}
abstract protected function escapeHtmlEntities($text, $flags = 0);
}