mirror of
https://github.com/erusev/parsedown.git
synced 2023-08-10 21:13:06 +03:00
Implement FencedCode
This commit is contained in:
parent
194c916c6a
commit
57c6350184
117
src/Components/Blocks/FencedCode.php
Normal file
117
src/Components/Blocks/FencedCode.php
Normal 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)]
|
||||||
|
)]);
|
||||||
|
}
|
||||||
|
}
|
@ -334,78 +334,6 @@ class Parsedown
|
|||||||
return $Block;
|
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
|
# Header
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user