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

123 lines
3.4 KiB
PHP
Raw Permalink 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
{
/** @var Lines */
private $Lines;
/**
* @param Lines $Lines
*/
private function __construct($Lines)
2019-01-20 05:25:04 +03:00
{
$this->Lines = $Lines;
}
/**
* @param Context $Context
* @param State $State
2019-01-20 05:25:04 +03:00
* @param Block|null $Block
* @return static|null
*/
public static function build(
Context $Context,
State $State,
Block $Block = null
2019-01-20 05:25:04 +03:00
) {
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") {
2019-02-03 00:07:53 +03:00
$recoveredSpaces = Line::tabShortage(0, $indentOffset -1) -1;
2019-01-20 05:25:04 +03:00
}
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
* @param State $State
2019-01-20 05:25:04 +03:00
* @return self|null
*/
public function advance(Context $Context, State $State)
2019-01-20 05:25:04 +03:00
{
if ($Context->previousEmptyLines() > 0) {
2019-01-20 05:25:04 +03:00
return null;
}
if (\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") {
2019-02-03 00:07:53 +03:00
$recoveredSpaces = Line::tabShortage(0, $indentOffset -1) -1;
2019-01-20 05:25:04 +03:00
}
$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 array{0: Block[], 1: State}
*/
public function contents(State $State)
{
return Parsedown::blocks($this->Lines, $State);
}
2019-01-20 05:25:04 +03:00
/**
* @return Handler<Element>
*/
public function stateRenderable()
2019-01-20 05:25:04 +03:00
{
return new Handler(
/** @return Element */
function (State $State) {
list($Blocks, $State) = $this->contents($State);
$StateRenderables = Parsedown::stateRenderablesFrom($Blocks);
$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
}
);
}
}