1
0
mirror of https://github.com/erusev/parsedown.git synced 2023-08-10 21:13:06 +03:00
parsedown/src/Components/Blocks/BlockQuote.php

120 lines
3.4 KiB
PHP
Raw Normal View History

2019-01-20 05:25:04 +03:00
<?php
namespace Erusev\Parsedown\Components\Blocks;
use Erusev\Parsedown\AST\Handler;
use Erusev\Parsedown\AST\StateRenderable;
use Erusev\Parsedown\Components\Block;
use Erusev\Parsedown\Components\ContinuableBlock;
use Erusev\Parsedown\Html\Renderables\Element;
2019-01-28 23:30:56 +03:00
use Erusev\Parsedown\Html\Renderables\Text;
2019-01-20 05:25:04 +03:00
use Erusev\Parsedown\Parsedown;
use Erusev\Parsedown\Parsing\Context;
use Erusev\Parsedown\Parsing\Line;
use Erusev\Parsedown\Parsing\Lines;
use Erusev\Parsedown\State;
final class BlockQuote implements ContinuableBlock
{
use BlockAcquisition;
2019-01-20 05:25:04 +03:00
/** @var Lines */
private $Lines;
/**
* @param Lines $Lines
*/
public function __construct($Lines)
{
$this->Lines = $Lines;
}
/**
* @param Context $Context
* @param Block|null $Block
* @param State|null $State
* @return static|null
*/
public static function build(
Context $Context,
Block $Block = null,
State $State = null
) {
if (\preg_match('/^(>[ \t]?+)(.*+)/', $Context->line()->text(), $matches)) {
$indentOffset = $Context->line()->indentOffset() + $Context->line()->indent() + \strlen($matches[1]);
$recoveredSpaces = 0;
if (\strlen($matches[1]) === 2 && \substr($matches[1], 1, 1) === "\t") {
$recoveredSpaces = Line::tabShortage(2, $Context->line()->indentOffset() + $Context->line()->indent());
}
2019-01-26 23:54:37 +03:00
return new self(Lines::fromTextLines(
2019-01-20 05:25:04 +03:00
\str_repeat(' ', $recoveredSpaces) . $matches[2],
$indentOffset
2019-01-26 23:54:37 +03:00
));
2019-01-20 05:25:04 +03:00
}
return null;
}
/**
* @param Context $Context
* @return self|null
*/
public function advance(Context $Context)
2019-01-20 05:25:04 +03:00
{
if ($Context->previousEmptyLines() > 0) {
2019-01-20 05:25:04 +03:00
return null;
}
2019-02-03 00:07:12 +03:00
if (
\substr($Context->line()->text(), 0, 1) === '>'
&& \preg_match('/^(>[ \t]?+)(.*+)/', $Context->line()->text(), $matches)
) {
2019-01-20 05:25:04 +03:00
$indentOffset = $Context->line()->indentOffset() + $Context->line()->indent() + \strlen($matches[1]);
$recoveredSpaces = 0;
if (\strlen($matches[1]) === 2 && \substr($matches[1], 1, 1) === "\t") {
$recoveredSpaces = Line::tabShortage(2, $Context->line()->indentOffset() + $Context->line()->indent());
}
$Lines = $this->Lines->appendingTextLines(
\str_repeat(' ', $recoveredSpaces) . $matches[2],
$indentOffset
);
return new self($Lines);
}
if (! $Context->previousEmptyLines() > 0) {
$indentOffset = $Context->line()->indentOffset() + $Context->line()->indent();
$Lines = $this->Lines->appendingTextLines($Context->line()->text(), $indentOffset);
return new self($Lines);
}
return null;
}
/**
* @return Handler<Element>
*/
public function stateRenderable()
2019-01-20 05:25:04 +03:00
{
return new Handler(
/** @return Element */
function (State $State) {
list($StateRenderables, $State) = Parsedown::lines(
$this->Lines,
$State
2019-01-20 05:25:04 +03:00
);
$Renderables = $State->applyTo($StateRenderables);
2019-01-28 23:30:56 +03:00
$Renderables[] = new Text("\n");
return new Element('blockquote', [], $Renderables);
2019-01-20 05:25:04 +03:00
}
);
}
}