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

Implement FencedCode

This commit is contained in:
Aidan Woods 2019-01-20 02:26:41 +00:00
parent 194c916c6a
commit 57c6350184
No known key found for this signature in database
GPG Key ID: 9A6A8EFAA512BBB9
2 changed files with 117 additions and 72 deletions

View File

@ -0,0 +1,117 @@
<?php
namespace Erusev\Parsedown\Components\Blocks;
use Erusev\Parsedown\AST\StateRenderable;
use Erusev\Parsedown\Components\Block;
use Erusev\Parsedown\Components\ContinuableBlock;
use Erusev\Parsedown\Html\Renderables\Element;
use Erusev\Parsedown\Html\Renderables\Text;
use Erusev\Parsedown\Parsedown;
use Erusev\Parsedown\Parsing\Context;
use Erusev\Parsedown\State;
final class FencedCode implements ContinuableBlock
{
use ContinuableBlockDefaultInterrupt, BlockAcquisition;
/** @var string */
private $code;
/** @var string */
private $infostring;
/** @var string */
private $marker;
/** @var int */
private $openerLength;
/** @var bool */
private $isComplete;
/**
* @param string $code
* @param string $infostring
* @param string $marker
* @param int $openerLength
* @param bool $isComplete
*/
public function __construct($code, $infostring, $marker, $openerLength, $isComplete)
{
$this->code = $code;
$this->infostring = $infostring;
$this->marker = $marker;
$this->openerLength = $openerLength;
$this->isComplete = $isComplete;
}
/**
* @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
) {
$marker = $Context->line()->text()[0];
$openerLength = \strspn($Context->line()->text(), $marker);
if ($openerLength < 3) {
return null;
}
$infostring = \trim(\substr($Context->line()->text(), $openerLength), "\t ");
if (\strpos($infostring, '`') !== false) {
return null;
}
return new self('', $infostring, $marker, $openerLength, false);
}
/**
* @param Context $Context
* @return self|null
*/
public function continue(Context $Context)
{
if ($this->isComplete) {
return null;
}
$newCode = $this->code;
if ($Context->previousEmptyLines() > 0) {
$newCode .= \str_repeat("\n", $Context->previousEmptyLines());
}
if (($len = \strspn($Context->line()->text(), $this->marker)) >= $this->openerLength
and \chop(\substr($Context->line()->text(), $len), ' ') === ''
) {
$newCode = \substr($newCode, 1);
return new self($newCode, $this->infostring, $this->marker, $this->openerLength, true);
}
$newCode .= "\n" . $Context->line()->rawLine();
return new self($newCode, $this->infostring, $this->marker, $this->openerLength, false);
}
/**
* @return Element
*/
public function stateRenderable(Parsedown $_)
{
return new Element('pre', [], [new Element(
'code',
$this->infostring !== '' ? ['class' => "language-{$this->infostring}"] : [],
[new Text($this->code)]
)]);
}
}

View File

@ -334,78 +334,6 @@ class Parsedown
return $Block;
}
#
# Fenced Code
protected function blockFencedCode(Context $Context)
{
$marker = $Context->line()->text()[0];
$openerLength = \strspn($Context->line()->text(), $marker);
if ($openerLength < 3) {
return;
}
$infostring = \trim(\substr($Context->line()->text(), $openerLength), "\t ");
if (\strpos($infostring, '`') !== false) {
return;
}
$Element = [
'name' => 'code',
'text' => '',
];
if ($infostring !== '') {
$Element['attributes'] = ['class' => "language-$infostring"];
}
$Block = [
'char' => $marker,
'openerLength' => $openerLength,
'element' => [
'name' => 'pre',
'element' => $Element,
],
];
return $Block;
}
protected function blockFencedCodeContinue(Context $Context, $Block)
{
if (isset($Block['complete'])) {
return;
}
if ($Context->previousEmptyLines() > 0) {
$Block['element']['element']['text'] .= \str_repeat("\n", $Context->previousEmptyLines());
unset($Block['interrupted']);
}
if (($len = \strspn($Context->line()->text(), $Block['char'])) >= $Block['openerLength']
and \chop(\substr($Context->line()->text(), $len), ' ') === ''
) {
$Block['element']['element']['text'] = \substr($Block['element']['element']['text'], 1);
$Block['complete'] = true;
return $Block;
}
$Block['element']['element']['text'] .= "\n" . $Context->line()->rawLine();
return $Block;
}
protected function blockFencedCodeComplete($Block)
{
return $Block;
}
#
# Header