laravel-6 support
This commit is contained in:
222
vendor/league/commonmark/src/Block/Element/AbstractBlock.php
vendored
Normal file
222
vendor/league/commonmark/src/Block/Element/AbstractBlock.php
vendored
Normal file
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Element;
|
||||
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
use League\CommonMark\Node\Node;
|
||||
|
||||
/**
|
||||
* Block-level element
|
||||
*
|
||||
* @method parent() ?AbstractBlock
|
||||
*/
|
||||
abstract class AbstractBlock extends Node
|
||||
{
|
||||
/**
|
||||
* Used for storage of arbitrary data.
|
||||
*
|
||||
* @var array<string, mixed>
|
||||
*/
|
||||
public $data = [];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $open = true;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $lastLineBlank = false;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $startLine = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $endLine = 0;
|
||||
|
||||
protected function setParent(Node $node = null)
|
||||
{
|
||||
if ($node && !$node instanceof self) {
|
||||
throw new \InvalidArgumentException('Parent of block must also be block (can not be inline)');
|
||||
}
|
||||
|
||||
parent::setParent($node);
|
||||
}
|
||||
|
||||
public function isContainer(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasChildren(): bool
|
||||
{
|
||||
return $this->firstChild !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this block can contain the given block as a child node
|
||||
*
|
||||
* @param AbstractBlock $block
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function canContain(AbstractBlock $block): bool;
|
||||
|
||||
/**
|
||||
* Whether this is a code block
|
||||
*
|
||||
* Code blocks are extra-greedy - they'll try to consume all subsequent
|
||||
* lines of content without calling matchesNextLine() each time.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function isCode(): bool;
|
||||
|
||||
/**
|
||||
* @param Cursor $cursor
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function matchesNextLine(Cursor $cursor): bool;
|
||||
|
||||
/**
|
||||
* @param int $startLine
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setStartLine(int $startLine)
|
||||
{
|
||||
$this->startLine = $startLine;
|
||||
if (empty($this->endLine)) {
|
||||
$this->endLine = $startLine;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getStartLine(): int
|
||||
{
|
||||
return $this->startLine;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $endLine
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setEndLine(int $endLine)
|
||||
{
|
||||
$this->endLine = $endLine;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getEndLine(): int
|
||||
{
|
||||
return $this->endLine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the block ends with a blank line
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function endsWithBlankLine(): bool
|
||||
{
|
||||
return $this->lastLineBlank;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $blank
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setLastLineBlank(bool $blank)
|
||||
{
|
||||
$this->lastLineBlank = $blank;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the last line should be marked as blank
|
||||
*
|
||||
* @param Cursor $cursor
|
||||
* @param int $currentLineNumber
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function shouldLastLineBeBlank(Cursor $cursor, int $currentLineNumber): bool
|
||||
{
|
||||
return $cursor->isBlank();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the block is open for modifications
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isOpen(): bool
|
||||
{
|
||||
return $this->open;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize the block; mark it closed for modification
|
||||
*
|
||||
* @param ContextInterface $context
|
||||
* @param int $endLineNumber
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function finalize(ContextInterface $context, int $endLineNumber)
|
||||
{
|
||||
if (!$this->open) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->open = false;
|
||||
$this->endLine = $endLineNumber;
|
||||
|
||||
// This should almost always be true
|
||||
if ($context->getTip() !== null) {
|
||||
$context->setTip($context->getTip()->parent());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData(string $key, $default = null)
|
||||
{
|
||||
return \array_key_exists($key, $this->data) ? $this->data[$key] : $default;
|
||||
}
|
||||
}
|
||||
55
vendor/league/commonmark/src/Block/Element/AbstractStringContainerBlock.php
vendored
Normal file
55
vendor/league/commonmark/src/Block/Element/AbstractStringContainerBlock.php
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Element;
|
||||
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
use League\CommonMark\Util\ArrayCollection;
|
||||
|
||||
/**
|
||||
* @method children() AbstractInline[]
|
||||
*/
|
||||
abstract class AbstractStringContainerBlock extends AbstractBlock implements StringContainerInterface
|
||||
{
|
||||
/**
|
||||
* @var ArrayCollection<int, string>
|
||||
*/
|
||||
protected $strings;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $finalStringContents = '';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->strings = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function addLine(string $line)
|
||||
{
|
||||
$this->strings[] = $line;
|
||||
}
|
||||
|
||||
abstract public function handleRemainingContents(ContextInterface $context, Cursor $cursor);
|
||||
|
||||
public function getStringContent(): string
|
||||
{
|
||||
return $this->finalStringContents;
|
||||
}
|
||||
}
|
||||
51
vendor/league/commonmark/src/Block/Element/BlockQuote.php
vendored
Normal file
51
vendor/league/commonmark/src/Block/Element/BlockQuote.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Element;
|
||||
|
||||
use League\CommonMark\Cursor;
|
||||
|
||||
/**
|
||||
* @method children() AbstractBlock[]
|
||||
*/
|
||||
class BlockQuote extends AbstractBlock
|
||||
{
|
||||
public function canContain(AbstractBlock $block): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isCode(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function matchesNextLine(Cursor $cursor): bool
|
||||
{
|
||||
if (!$cursor->isIndented() && $cursor->getNextNonSpaceCharacter() === '>') {
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
$cursor->advanceBy(1);
|
||||
$cursor->advanceBySpaceOrTab();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function shouldLastLineBeBlank(Cursor $cursor, int $currentLineNumber): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
58
vendor/league/commonmark/src/Block/Element/Document.php
vendored
Normal file
58
vendor/league/commonmark/src/Block/Element/Document.php
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Element;
|
||||
|
||||
use League\CommonMark\Cursor;
|
||||
use League\CommonMark\Reference\ReferenceMap;
|
||||
use League\CommonMark\Reference\ReferenceMapInterface;
|
||||
|
||||
/**
|
||||
* @method children() AbstractBlock[]
|
||||
*/
|
||||
class Document extends AbstractBlock
|
||||
{
|
||||
/** @var ReferenceMapInterface */
|
||||
protected $referenceMap;
|
||||
|
||||
public function __construct(?ReferenceMapInterface $referenceMap = null)
|
||||
{
|
||||
$this->setStartLine(1);
|
||||
|
||||
$this->referenceMap = $referenceMap ?? new ReferenceMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ReferenceMapInterface
|
||||
*/
|
||||
public function getReferenceMap(): ReferenceMapInterface
|
||||
{
|
||||
return $this->referenceMap;
|
||||
}
|
||||
|
||||
public function canContain(AbstractBlock $block): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isCode(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function matchesNextLine(Cursor $cursor): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
201
vendor/league/commonmark/src/Block/Element/FencedCode.php
vendored
Normal file
201
vendor/league/commonmark/src/Block/Element/FencedCode.php
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Element;
|
||||
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
class FencedCode extends AbstractStringContainerBlock
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $info;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $length;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $char;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $offset;
|
||||
|
||||
/**
|
||||
* @param int $length
|
||||
* @param string $char
|
||||
* @param int $offset
|
||||
*/
|
||||
public function __construct(int $length, string $char, int $offset)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->length = $length;
|
||||
$this->char = $char;
|
||||
$this->offset = $offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getInfo(): string
|
||||
{
|
||||
return $this->info;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getInfoWords(): array
|
||||
{
|
||||
return \preg_split('/\s+/', $this->info) ?: [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getChar(): string
|
||||
{
|
||||
return $this->char;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $char
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setChar(string $char): self
|
||||
{
|
||||
$this->char = $char;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLength(): int
|
||||
{
|
||||
return $this->length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $length
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setLength(int $length): self
|
||||
{
|
||||
$this->length = $length;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getOffset(): int
|
||||
{
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setOffset(int $offset): self
|
||||
{
|
||||
$this->offset = $offset;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function canContain(AbstractBlock $block): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isCode(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function matchesNextLine(Cursor $cursor): bool
|
||||
{
|
||||
if ($this->length === -1) {
|
||||
if ($cursor->isBlank()) {
|
||||
$this->lastLineBlank = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip optional spaces of fence offset
|
||||
$cursor->match('/^ {0,' . $this->offset . '}/');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function finalize(ContextInterface $context, int $endLineNumber)
|
||||
{
|
||||
parent::finalize($context, $endLineNumber);
|
||||
|
||||
// first line becomes info string
|
||||
$firstLine = $this->strings->first();
|
||||
if ($firstLine === false) {
|
||||
$firstLine = '';
|
||||
}
|
||||
|
||||
$this->info = RegexHelper::unescape(\trim($firstLine));
|
||||
|
||||
if ($this->strings->count() === 1) {
|
||||
$this->finalStringContents = '';
|
||||
} else {
|
||||
$this->finalStringContents = \implode("\n", $this->strings->slice(1)) . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
public function handleRemainingContents(ContextInterface $context, Cursor $cursor)
|
||||
{
|
||||
/** @var self $container */
|
||||
$container = $context->getContainer();
|
||||
|
||||
// check for closing code fence
|
||||
if ($cursor->getIndent() <= 3 && $cursor->getNextNonSpaceCharacter() === $container->getChar()) {
|
||||
$match = RegexHelper::matchFirst('/^(?:`{3,}|~{3,})(?= *$)/', $cursor->getLine(), $cursor->getNextNonSpacePosition());
|
||||
if ($match !== null && \strlen($match[0]) >= $container->getLength()) {
|
||||
// don't add closing fence to container; instead, close it:
|
||||
$this->setLength(-1); // -1 means we've passed closer
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$container->addLine($cursor->getRemainder());
|
||||
}
|
||||
|
||||
public function shouldLastLineBeBlank(Cursor $cursor, int $currentLineNumber): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
80
vendor/league/commonmark/src/Block/Element/Heading.php
vendored
Normal file
80
vendor/league/commonmark/src/Block/Element/Heading.php
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Element;
|
||||
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
|
||||
class Heading extends AbstractStringContainerBlock implements InlineContainerInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $level;
|
||||
|
||||
/**
|
||||
* @param int $level
|
||||
* @param string|string[] $contents
|
||||
*/
|
||||
public function __construct(int $level, $contents)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->level = $level;
|
||||
|
||||
if (!\is_array($contents)) {
|
||||
$contents = [$contents];
|
||||
}
|
||||
|
||||
foreach ($contents as $line) {
|
||||
$this->addLine($line);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLevel(): int
|
||||
{
|
||||
return $this->level;
|
||||
}
|
||||
|
||||
public function finalize(ContextInterface $context, int $endLineNumber)
|
||||
{
|
||||
parent::finalize($context, $endLineNumber);
|
||||
|
||||
$this->finalStringContents = \implode("\n", $this->strings->toArray());
|
||||
}
|
||||
|
||||
public function canContain(AbstractBlock $block): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isCode(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function matchesNextLine(Cursor $cursor): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function handleRemainingContents(ContextInterface $context, Cursor $cursor)
|
||||
{
|
||||
// nothing to do; contents were already added via the constructor.
|
||||
}
|
||||
}
|
||||
104
vendor/league/commonmark/src/Block/Element/HtmlBlock.php
vendored
Normal file
104
vendor/league/commonmark/src/Block/Element/HtmlBlock.php
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Element;
|
||||
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
class HtmlBlock extends AbstractStringContainerBlock
|
||||
{
|
||||
// Any changes to these constants should be reflected in .phpstorm.meta.php
|
||||
const TYPE_1_CODE_CONTAINER = 1;
|
||||
const TYPE_2_COMMENT = 2;
|
||||
const TYPE_3 = 3;
|
||||
const TYPE_4 = 4;
|
||||
const TYPE_5_CDATA = 5;
|
||||
const TYPE_6_BLOCK_ELEMENT = 6;
|
||||
const TYPE_7_MISC_ELEMENT = 7;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* @param int $type
|
||||
*/
|
||||
public function __construct(int $type)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getType(): int
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setType(int $type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
public function canContain(AbstractBlock $block): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isCode(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function matchesNextLine(Cursor $cursor): bool
|
||||
{
|
||||
if ($cursor->isBlank() && ($this->type === self::TYPE_6_BLOCK_ELEMENT || $this->type === self::TYPE_7_MISC_ELEMENT)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function finalize(ContextInterface $context, int $endLineNumber)
|
||||
{
|
||||
parent::finalize($context, $endLineNumber);
|
||||
|
||||
$this->finalStringContents = \implode("\n", $this->strings->toArray());
|
||||
}
|
||||
|
||||
public function handleRemainingContents(ContextInterface $context, Cursor $cursor)
|
||||
{
|
||||
/** @var self $tip */
|
||||
$tip = $context->getTip();
|
||||
$tip->addLine($cursor->getRemainder());
|
||||
|
||||
// Check for end condition
|
||||
if ($this->type >= self::TYPE_1_CODE_CONTAINER && $this->type <= self::TYPE_5_CDATA) {
|
||||
if ($cursor->match(RegexHelper::getHtmlBlockCloseRegex($this->type)) !== null) {
|
||||
$this->finalize($context, $context->getLineNumber());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
72
vendor/league/commonmark/src/Block/Element/IndentedCode.php
vendored
Normal file
72
vendor/league/commonmark/src/Block/Element/IndentedCode.php
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Element;
|
||||
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
|
||||
class IndentedCode extends AbstractStringContainerBlock
|
||||
{
|
||||
public function canContain(AbstractBlock $block): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isCode(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function matchesNextLine(Cursor $cursor): bool
|
||||
{
|
||||
if ($cursor->isIndented()) {
|
||||
$cursor->advanceBy(Cursor::INDENT_LEVEL, true);
|
||||
} elseif ($cursor->isBlank()) {
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function finalize(ContextInterface $context, int $endLineNumber)
|
||||
{
|
||||
parent::finalize($context, $endLineNumber);
|
||||
|
||||
$reversed = \array_reverse($this->strings->toArray(), true);
|
||||
foreach ($reversed as $index => $line) {
|
||||
if ($line === '' || $line === "\n" || \preg_match('/^(\n *)$/', $line)) {
|
||||
unset($reversed[$index]);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$fixed = \array_reverse($reversed);
|
||||
$tmp = \implode("\n", $fixed);
|
||||
if (\substr($tmp, -1) !== "\n") {
|
||||
$tmp .= "\n";
|
||||
}
|
||||
|
||||
$this->finalStringContents = $tmp;
|
||||
}
|
||||
|
||||
public function handleRemainingContents(ContextInterface $context, Cursor $cursor)
|
||||
{
|
||||
/** @var self $tip */
|
||||
$tip = $context->getTip();
|
||||
$tip->addLine($cursor->getRemainder());
|
||||
}
|
||||
}
|
||||
20
vendor/league/commonmark/src/Block/Element/InlineContainerInterface.php
vendored
Normal file
20
vendor/league/commonmark/src/Block/Element/InlineContainerInterface.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Element;
|
||||
|
||||
interface InlineContainerInterface extends StringContainerInterface
|
||||
{
|
||||
public function getStringContent(): string;
|
||||
}
|
||||
123
vendor/league/commonmark/src/Block/Element/ListBlock.php
vendored
Normal file
123
vendor/league/commonmark/src/Block/Element/ListBlock.php
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Element;
|
||||
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
|
||||
/**
|
||||
* @method children() AbstractBlock[]
|
||||
*/
|
||||
class ListBlock extends AbstractBlock
|
||||
{
|
||||
const TYPE_BULLET = 'bullet';
|
||||
const TYPE_ORDERED = 'ordered';
|
||||
|
||||
/**
|
||||
* @deprecated This constant is deprecated in league/commonmark 1.4 and will be removed in 2.0; use TYPE_BULLET instead
|
||||
*/
|
||||
const TYPE_UNORDERED = self::TYPE_BULLET;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $tight = false;
|
||||
|
||||
/**
|
||||
* @var ListData
|
||||
*/
|
||||
protected $listData;
|
||||
|
||||
public function __construct(ListData $listData)
|
||||
{
|
||||
$this->listData = $listData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ListData
|
||||
*/
|
||||
public function getListData(): ListData
|
||||
{
|
||||
return $this->listData;
|
||||
}
|
||||
|
||||
public function endsWithBlankLine(): bool
|
||||
{
|
||||
if ($this->lastLineBlank) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->hasChildren()) {
|
||||
return $this->lastChild() instanceof AbstractBlock && $this->lastChild()->endsWithBlankLine();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canContain(AbstractBlock $block): bool
|
||||
{
|
||||
return $block instanceof ListItem;
|
||||
}
|
||||
|
||||
public function isCode(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function matchesNextLine(Cursor $cursor): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function finalize(ContextInterface $context, int $endLineNumber)
|
||||
{
|
||||
parent::finalize($context, $endLineNumber);
|
||||
|
||||
$this->tight = true; // tight by default
|
||||
|
||||
foreach ($this->children() as $item) {
|
||||
if (!($item instanceof AbstractBlock)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check for non-final list item ending with blank line:
|
||||
if ($item->endsWithBlankLine() && $item !== $this->lastChild()) {
|
||||
$this->tight = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Recurse into children of list item, to see if there are
|
||||
// spaces between any of them:
|
||||
foreach ($item->children() as $subItem) {
|
||||
if ($subItem instanceof AbstractBlock && $subItem->endsWithBlankLine() && ($item !== $this->lastChild() || $subItem !== $item->lastChild())) {
|
||||
$this->tight = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function isTight(): bool
|
||||
{
|
||||
return $this->tight;
|
||||
}
|
||||
|
||||
public function setTight(bool $tight): self
|
||||
{
|
||||
$this->tight = $tight;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
60
vendor/league/commonmark/src/Block/Element/ListData.php
vendored
Normal file
60
vendor/league/commonmark/src/Block/Element/ListData.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Element;
|
||||
|
||||
class ListData
|
||||
{
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
public $start;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $padding = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $type;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $delimiter;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $bulletChar;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $markerOffset;
|
||||
|
||||
/**
|
||||
* @param ListData $data
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function equals(ListData $data)
|
||||
{
|
||||
return $this->type === $data->type &&
|
||||
$this->delimiter === $data->delimiter &&
|
||||
$this->bulletChar === $data->bulletChar;
|
||||
}
|
||||
}
|
||||
73
vendor/league/commonmark/src/Block/Element/ListItem.php
vendored
Normal file
73
vendor/league/commonmark/src/Block/Element/ListItem.php
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Element;
|
||||
|
||||
use League\CommonMark\Cursor;
|
||||
|
||||
/**
|
||||
* @method children() AbstractBlock[]
|
||||
*/
|
||||
class ListItem extends AbstractBlock
|
||||
{
|
||||
/**
|
||||
* @var ListData
|
||||
*/
|
||||
protected $listData;
|
||||
|
||||
public function __construct(ListData $listData)
|
||||
{
|
||||
$this->listData = $listData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ListData
|
||||
*/
|
||||
public function getListData(): ListData
|
||||
{
|
||||
return $this->listData;
|
||||
}
|
||||
|
||||
public function canContain(AbstractBlock $block): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isCode(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function matchesNextLine(Cursor $cursor): bool
|
||||
{
|
||||
if ($cursor->isBlank()) {
|
||||
if ($this->firstChild === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
} elseif ($cursor->getIndent() >= $this->listData->markerOffset + $this->listData->padding) {
|
||||
$cursor->advanceBy($this->listData->markerOffset + $this->listData->padding, true);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function shouldLastLineBeBlank(Cursor $cursor, int $currentLineNumber): bool
|
||||
{
|
||||
return $cursor->isBlank() && $this->startLine < $currentLineNumber;
|
||||
}
|
||||
}
|
||||
98
vendor/league/commonmark/src/Block/Element/Paragraph.php
vendored
Normal file
98
vendor/league/commonmark/src/Block/Element/Paragraph.php
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Element;
|
||||
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
|
||||
class Paragraph extends AbstractStringContainerBlock implements InlineContainerInterface
|
||||
{
|
||||
public function canContain(AbstractBlock $block): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isCode(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function matchesNextLine(Cursor $cursor): bool
|
||||
{
|
||||
if ($cursor->isBlank()) {
|
||||
$this->lastLineBlank = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function finalize(ContextInterface $context, int $endLineNumber)
|
||||
{
|
||||
parent::finalize($context, $endLineNumber);
|
||||
|
||||
$this->finalStringContents = \preg_replace('/^ */m', '', \implode("\n", $this->getStrings()));
|
||||
|
||||
// Short-circuit
|
||||
if ($this->finalStringContents === '' || $this->finalStringContents[0] !== '[') {
|
||||
return;
|
||||
}
|
||||
|
||||
$cursor = new Cursor($this->finalStringContents);
|
||||
|
||||
$referenceFound = $this->parseReferences($context, $cursor);
|
||||
|
||||
$this->finalStringContents = $cursor->getRemainder();
|
||||
|
||||
if ($referenceFound && $cursor->isAtEnd()) {
|
||||
$this->detach();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ContextInterface $context
|
||||
* @param Cursor $cursor
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function parseReferences(ContextInterface $context, Cursor $cursor)
|
||||
{
|
||||
$referenceFound = false;
|
||||
while ($cursor->getCharacter() === '[' && $context->getReferenceParser()->parse($cursor)) {
|
||||
$this->finalStringContents = $cursor->getRemainder();
|
||||
$referenceFound = true;
|
||||
}
|
||||
|
||||
return $referenceFound;
|
||||
}
|
||||
|
||||
public function handleRemainingContents(ContextInterface $context, Cursor $cursor)
|
||||
{
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
|
||||
/** @var self $tip */
|
||||
$tip = $context->getTip();
|
||||
$tip->addLine($cursor->getRemainder());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getStrings(): array
|
||||
{
|
||||
return $this->strings->toArray();
|
||||
}
|
||||
}
|
||||
44
vendor/league/commonmark/src/Block/Element/StringContainerInterface.php
vendored
Normal file
44
vendor/league/commonmark/src/Block/Element/StringContainerInterface.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Element;
|
||||
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
|
||||
/**
|
||||
* Interface for a block which can contain line(s) of strings
|
||||
*/
|
||||
interface StringContainerInterface
|
||||
{
|
||||
/**
|
||||
* @param string $line
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addLine(string $line);
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getStringContent(): string;
|
||||
|
||||
/**
|
||||
* @param ContextInterface $context
|
||||
* @param Cursor $cursor
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handleRemainingContents(ContextInterface $context, Cursor $cursor);
|
||||
}
|
||||
35
vendor/league/commonmark/src/Block/Element/ThematicBreak.php
vendored
Normal file
35
vendor/league/commonmark/src/Block/Element/ThematicBreak.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Element;
|
||||
|
||||
use League\CommonMark\Cursor;
|
||||
|
||||
class ThematicBreak extends AbstractBlock
|
||||
{
|
||||
public function canContain(AbstractBlock $block): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isCode(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function matchesNextLine(Cursor $cursor): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
51
vendor/league/commonmark/src/Block/Parser/ATXHeadingParser.php
vendored
Normal file
51
vendor/league/commonmark/src/Block/Parser/ATXHeadingParser.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Parser;
|
||||
|
||||
use League\CommonMark\Block\Element\Heading;
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
final class ATXHeadingParser implements BlockParserInterface
|
||||
{
|
||||
public function parse(ContextInterface $context, Cursor $cursor): bool
|
||||
{
|
||||
if ($cursor->isIndented()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$match = RegexHelper::matchFirst('/^#{1,6}(?:[ \t]+|$)/', $cursor->getLine(), $cursor->getNextNonSpacePosition());
|
||||
if (!$match) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
|
||||
$cursor->advanceBy(\strlen($match[0]));
|
||||
|
||||
$level = \strlen(\trim($match[0]));
|
||||
$str = $cursor->getRemainder();
|
||||
/** @var string $str */
|
||||
$str = \preg_replace('/^[ \t]*#+[ \t]*$/', '', $str);
|
||||
/** @var string $str */
|
||||
$str = \preg_replace('/[ \t]+#+[ \t]*$/', '', $str);
|
||||
|
||||
$context->addBlock(new Heading($level, $str));
|
||||
$context->setBlocksParsed(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
29
vendor/league/commonmark/src/Block/Parser/BlockParserInterface.php
vendored
Normal file
29
vendor/league/commonmark/src/Block/Parser/BlockParserInterface.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Parser;
|
||||
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
|
||||
interface BlockParserInterface
|
||||
{
|
||||
/**
|
||||
* @param ContextInterface $context
|
||||
* @param Cursor $cursor
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function parse(ContextInterface $context, Cursor $cursor): bool;
|
||||
}
|
||||
41
vendor/league/commonmark/src/Block/Parser/BlockQuoteParser.php
vendored
Normal file
41
vendor/league/commonmark/src/Block/Parser/BlockQuoteParser.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Parser;
|
||||
|
||||
use League\CommonMark\Block\Element\BlockQuote;
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
|
||||
final class BlockQuoteParser implements BlockParserInterface
|
||||
{
|
||||
public function parse(ContextInterface $context, Cursor $cursor): bool
|
||||
{
|
||||
if ($cursor->isIndented()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($cursor->getNextNonSpaceCharacter() !== '>') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
$cursor->advanceBy(1);
|
||||
$cursor->advanceBySpaceOrTab();
|
||||
|
||||
$context->addBlock(new BlockQuote());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
47
vendor/league/commonmark/src/Block/Parser/FencedCodeParser.php
vendored
Normal file
47
vendor/league/commonmark/src/Block/Parser/FencedCodeParser.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Parser;
|
||||
|
||||
use League\CommonMark\Block\Element\FencedCode;
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
|
||||
final class FencedCodeParser implements BlockParserInterface
|
||||
{
|
||||
public function parse(ContextInterface $context, Cursor $cursor): bool
|
||||
{
|
||||
if ($cursor->isIndented()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$c = $cursor->getCharacter();
|
||||
if ($c !== ' ' && $c !== "\t" && $c !== '`' && $c !== '~') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$indent = $cursor->getIndent();
|
||||
$fence = $cursor->match('/^[ \t]*(?:`{3,}(?!.*`)|~{3,})/');
|
||||
if ($fence === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// fenced code block
|
||||
$fence = \ltrim($fence, " \t");
|
||||
$fenceLength = \strlen($fence);
|
||||
$context->addBlock(new FencedCode($fenceLength, $fence[0], $indent));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
59
vendor/league/commonmark/src/Block/Parser/HtmlBlockParser.php
vendored
Normal file
59
vendor/league/commonmark/src/Block/Parser/HtmlBlockParser.php
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Parser;
|
||||
|
||||
use League\CommonMark\Block\Element\HtmlBlock;
|
||||
use League\CommonMark\Block\Element\Paragraph;
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
final class HtmlBlockParser implements BlockParserInterface
|
||||
{
|
||||
public function parse(ContextInterface $context, Cursor $cursor): bool
|
||||
{
|
||||
if ($cursor->isIndented()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($cursor->getNextNonSpaceCharacter() !== '<') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$savedState = $cursor->saveState();
|
||||
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
$line = $cursor->getRemainder();
|
||||
|
||||
for ($blockType = 1; $blockType <= 7; $blockType++) {
|
||||
$match = RegexHelper::matchAt(
|
||||
RegexHelper::getHtmlBlockOpenRegex($blockType),
|
||||
$line
|
||||
);
|
||||
|
||||
if ($match !== null && ($blockType < 7 || !($context->getContainer() instanceof Paragraph))) {
|
||||
$cursor->restoreState($savedState);
|
||||
$context->addBlock(new HtmlBlock($blockType));
|
||||
$context->setBlocksParsed(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$cursor->restoreState($savedState);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
43
vendor/league/commonmark/src/Block/Parser/IndentedCodeParser.php
vendored
Normal file
43
vendor/league/commonmark/src/Block/Parser/IndentedCodeParser.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Parser;
|
||||
|
||||
use League\CommonMark\Block\Element\IndentedCode;
|
||||
use League\CommonMark\Block\Element\Paragraph;
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
|
||||
final class IndentedCodeParser implements BlockParserInterface
|
||||
{
|
||||
public function parse(ContextInterface $context, Cursor $cursor): bool
|
||||
{
|
||||
if (!$cursor->isIndented()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($context->getTip() instanceof Paragraph) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($cursor->isBlank()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cursor->advanceBy(Cursor::INDENT_LEVEL, true);
|
||||
$context->addBlock(new IndentedCode());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
32
vendor/league/commonmark/src/Block/Parser/LazyParagraphParser.php
vendored
Normal file
32
vendor/league/commonmark/src/Block/Parser/LazyParagraphParser.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Parser;
|
||||
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
|
||||
final class LazyParagraphParser implements BlockParserInterface
|
||||
{
|
||||
public function parse(ContextInterface $context, Cursor $cursor): bool
|
||||
{
|
||||
if (!$cursor->isIndented()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$context->setBlocksParsed(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
154
vendor/league/commonmark/src/Block/Parser/ListParser.php
vendored
Normal file
154
vendor/league/commonmark/src/Block/Parser/ListParser.php
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Parser;
|
||||
|
||||
use League\CommonMark\Block\Element\ListBlock;
|
||||
use League\CommonMark\Block\Element\ListData;
|
||||
use League\CommonMark\Block\Element\ListItem;
|
||||
use League\CommonMark\Block\Element\Paragraph;
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
use League\CommonMark\Util\ConfigurationAwareInterface;
|
||||
use League\CommonMark\Util\ConfigurationInterface;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
final class ListParser implements BlockParserInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @var ConfigurationInterface|null */
|
||||
private $config;
|
||||
|
||||
/** @var string|null */
|
||||
private $listMarkerRegex;
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration)
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
|
||||
public function parse(ContextInterface $context, Cursor $cursor): bool
|
||||
{
|
||||
if ($cursor->isIndented() && !($context->getContainer() instanceof ListBlock)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$indent = $cursor->getIndent();
|
||||
if ($indent >= 4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$tmpCursor = clone $cursor;
|
||||
$tmpCursor->advanceToNextNonSpaceOrTab();
|
||||
$rest = $tmpCursor->getRemainder();
|
||||
|
||||
if (\preg_match($this->listMarkerRegex ?? $this->generateListMarkerRegex(), $rest) === 1) {
|
||||
$data = new ListData();
|
||||
$data->markerOffset = $indent;
|
||||
$data->type = ListBlock::TYPE_BULLET;
|
||||
$data->delimiter = null;
|
||||
$data->bulletChar = $rest[0];
|
||||
$markerLength = 1;
|
||||
} elseif (($matches = RegexHelper::matchFirst('/^(\d{1,9})([.)])/', $rest)) && (!($context->getContainer() instanceof Paragraph) || $matches[1] === '1')) {
|
||||
$data = new ListData();
|
||||
$data->markerOffset = $indent;
|
||||
$data->type = ListBlock::TYPE_ORDERED;
|
||||
$data->start = (int) $matches[1];
|
||||
$data->delimiter = $matches[2];
|
||||
$data->bulletChar = null;
|
||||
$markerLength = \strlen($matches[0]);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure we have spaces after
|
||||
$nextChar = $tmpCursor->peek($markerLength);
|
||||
if (!($nextChar === null || $nextChar === "\t" || $nextChar === ' ')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If it interrupts paragraph, make sure first line isn't blank
|
||||
$container = $context->getContainer();
|
||||
if ($container instanceof Paragraph && !RegexHelper::matchAt(RegexHelper::REGEX_NON_SPACE, $rest, $markerLength)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We've got a match! Advance offset and calculate padding
|
||||
$cursor->advanceToNextNonSpaceOrTab(); // to start of marker
|
||||
$cursor->advanceBy($markerLength, true); // to end of marker
|
||||
$data->padding = $this->calculateListMarkerPadding($cursor, $markerLength);
|
||||
|
||||
// add the list if needed
|
||||
if (!($container instanceof ListBlock) || !$data->equals($container->getListData())) {
|
||||
$context->addBlock(new ListBlock($data));
|
||||
}
|
||||
|
||||
// add the list item
|
||||
$context->addBlock(new ListItem($data));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Cursor $cursor
|
||||
* @param int $markerLength
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function calculateListMarkerPadding(Cursor $cursor, int $markerLength): int
|
||||
{
|
||||
$start = $cursor->saveState();
|
||||
$spacesStartCol = $cursor->getColumn();
|
||||
|
||||
while ($cursor->getColumn() - $spacesStartCol < 5) {
|
||||
if (!$cursor->advanceBySpaceOrTab()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$blankItem = $cursor->peek() === null;
|
||||
$spacesAfterMarker = $cursor->getColumn() - $spacesStartCol;
|
||||
|
||||
if ($spacesAfterMarker >= 5 || $spacesAfterMarker < 1 || $blankItem) {
|
||||
$cursor->restoreState($start);
|
||||
$cursor->advanceBySpaceOrTab();
|
||||
|
||||
return $markerLength + 1;
|
||||
}
|
||||
|
||||
return $markerLength + $spacesAfterMarker;
|
||||
}
|
||||
|
||||
private function generateListMarkerRegex(): string
|
||||
{
|
||||
// No configuration given - use the defaults
|
||||
if ($this->config === null) {
|
||||
return $this->listMarkerRegex = '/^[*+-]/';
|
||||
}
|
||||
|
||||
$deprecatedMarkers = $this->config->get('unordered_list_markers', ConfigurationInterface::MISSING);
|
||||
if ($deprecatedMarkers !== ConfigurationInterface::MISSING) {
|
||||
@\trigger_error('The "unordered_list_markers" configuration option is deprecated in league/commonmark 1.6 and will be replaced with "commonmark > unordered_list_markers" in 2.0', \E_USER_DEPRECATED);
|
||||
} else {
|
||||
$deprecatedMarkers = ['*', '+', '-'];
|
||||
}
|
||||
|
||||
$markers = $this->config->get('commonmark/unordered_list_markers', $deprecatedMarkers);
|
||||
|
||||
if (!\is_array($markers) || $markers === []) {
|
||||
throw new \RuntimeException('Invalid configuration option "unordered_list_markers": value must be an array of strings');
|
||||
}
|
||||
|
||||
return $this->listMarkerRegex = '/^[' . \preg_quote(\implode('', $markers), '/') . ']/';
|
||||
}
|
||||
}
|
||||
81
vendor/league/commonmark/src/Block/Parser/SetExtHeadingParser.php
vendored
Normal file
81
vendor/league/commonmark/src/Block/Parser/SetExtHeadingParser.php
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Parser;
|
||||
|
||||
use League\CommonMark\Block\Element\Heading;
|
||||
use League\CommonMark\Block\Element\Paragraph;
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
use League\CommonMark\Reference\ReferenceParser;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
final class SetExtHeadingParser implements BlockParserInterface
|
||||
{
|
||||
public function parse(ContextInterface $context, Cursor $cursor): bool
|
||||
{
|
||||
if ($cursor->isIndented()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!($context->getContainer() instanceof Paragraph)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$match = RegexHelper::matchFirst('/^(?:=+|-+)[ \t]*$/', $cursor->getLine(), $cursor->getNextNonSpacePosition());
|
||||
if ($match === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$level = $match[0][0] === '=' ? 1 : 2;
|
||||
$strings = $context->getContainer()->getStrings();
|
||||
|
||||
$strings = $this->resolveReferenceLinkDefinitions($strings, $context->getReferenceParser());
|
||||
if (empty($strings)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$context->replaceContainerBlock(new Heading($level, $strings));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve reference link definition
|
||||
*
|
||||
* @see https://github.com/commonmark/commonmark.js/commit/993bbe335931af847460effa99b2411eb643577d
|
||||
*
|
||||
* @param string[] $strings
|
||||
* @param ReferenceParser $referenceParser
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private function resolveReferenceLinkDefinitions(array $strings, ReferenceParser $referenceParser): array
|
||||
{
|
||||
foreach ($strings as &$string) {
|
||||
$cursor = new Cursor($string);
|
||||
while ($cursor->getCharacter() === '[' && $referenceParser->parse($cursor)) {
|
||||
$string = $cursor->getRemainder();
|
||||
}
|
||||
|
||||
if ($string !== '') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return \array_filter($strings, function ($s) {
|
||||
return $s !== '';
|
||||
});
|
||||
}
|
||||
}
|
||||
43
vendor/league/commonmark/src/Block/Parser/ThematicBreakParser.php
vendored
Normal file
43
vendor/league/commonmark/src/Block/Parser/ThematicBreakParser.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Parser;
|
||||
|
||||
use League\CommonMark\Block\Element\ThematicBreak;
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
final class ThematicBreakParser implements BlockParserInterface
|
||||
{
|
||||
public function parse(ContextInterface $context, Cursor $cursor): bool
|
||||
{
|
||||
if ($cursor->isIndented()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$match = RegexHelper::matchAt(RegexHelper::REGEX_THEMATIC_BREAK, $cursor->getLine(), $cursor->getNextNonSpacePosition());
|
||||
if ($match === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Advance to the end of the string, consuming the entire line (of the thematic break)
|
||||
$cursor->advanceToEnd();
|
||||
|
||||
$context->addBlock(new ThematicBreak());
|
||||
$context->setBlocksParsed(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
50
vendor/league/commonmark/src/Block/Renderer/BlockQuoteRenderer.php
vendored
Normal file
50
vendor/league/commonmark/src/Block/Renderer/BlockQuoteRenderer.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Renderer;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Block\Element\BlockQuote;
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\HtmlElement;
|
||||
|
||||
final class BlockQuoteRenderer implements BlockRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param BlockQuote $block
|
||||
* @param ElementRendererInterface $htmlRenderer
|
||||
* @param bool $inTightList
|
||||
*
|
||||
* @return HtmlElement
|
||||
*/
|
||||
public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, bool $inTightList = false)
|
||||
{
|
||||
if (!($block instanceof BlockQuote)) {
|
||||
throw new \InvalidArgumentException('Incompatible block type: ' . \get_class($block));
|
||||
}
|
||||
|
||||
$attrs = $block->getData('attributes', []);
|
||||
|
||||
$filling = $htmlRenderer->renderBlocks($block->children());
|
||||
if ($filling === '') {
|
||||
return new HtmlElement('blockquote', $attrs, $htmlRenderer->getOption('inner_separator', "\n"));
|
||||
}
|
||||
|
||||
return new HtmlElement(
|
||||
'blockquote',
|
||||
$attrs,
|
||||
$htmlRenderer->getOption('inner_separator', "\n") . $filling . $htmlRenderer->getOption('inner_separator', "\n")
|
||||
);
|
||||
}
|
||||
}
|
||||
31
vendor/league/commonmark/src/Block/Renderer/BlockRendererInterface.php
vendored
Normal file
31
vendor/league/commonmark/src/Block/Renderer/BlockRendererInterface.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Renderer;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\HtmlElement;
|
||||
|
||||
interface BlockRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param AbstractBlock $block
|
||||
* @param ElementRendererInterface $htmlRenderer
|
||||
* @param bool $inTightList
|
||||
*
|
||||
* @return HtmlElement|string|null
|
||||
*/
|
||||
public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, bool $inTightList = false);
|
||||
}
|
||||
40
vendor/league/commonmark/src/Block/Renderer/DocumentRenderer.php
vendored
Normal file
40
vendor/league/commonmark/src/Block/Renderer/DocumentRenderer.php
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Renderer;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Block\Element\Document;
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
|
||||
final class DocumentRenderer implements BlockRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param Document $block
|
||||
* @param ElementRendererInterface $htmlRenderer
|
||||
* @param bool $inTightList
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, bool $inTightList = false)
|
||||
{
|
||||
if (!($block instanceof Document)) {
|
||||
throw new \InvalidArgumentException('Incompatible block type: ' . \get_class($block));
|
||||
}
|
||||
|
||||
$wholeDoc = $htmlRenderer->renderBlocks($block->children());
|
||||
|
||||
return $wholeDoc === '' ? '' : $wholeDoc . "\n";
|
||||
}
|
||||
}
|
||||
52
vendor/league/commonmark/src/Block/Renderer/FencedCodeRenderer.php
vendored
Normal file
52
vendor/league/commonmark/src/Block/Renderer/FencedCodeRenderer.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Renderer;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Block\Element\FencedCode;
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\HtmlElement;
|
||||
use League\CommonMark\Util\Xml;
|
||||
|
||||
final class FencedCodeRenderer implements BlockRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param FencedCode $block
|
||||
* @param ElementRendererInterface $htmlRenderer
|
||||
* @param bool $inTightList
|
||||
*
|
||||
* @return HtmlElement
|
||||
*/
|
||||
public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, bool $inTightList = false)
|
||||
{
|
||||
if (!($block instanceof FencedCode)) {
|
||||
throw new \InvalidArgumentException('Incompatible block type: ' . \get_class($block));
|
||||
}
|
||||
|
||||
$attrs = $block->getData('attributes', []);
|
||||
|
||||
$infoWords = $block->getInfoWords();
|
||||
if (\count($infoWords) !== 0 && \strlen($infoWords[0]) !== 0) {
|
||||
$attrs['class'] = isset($attrs['class']) ? $attrs['class'] . ' ' : '';
|
||||
$attrs['class'] .= 'language-' . $infoWords[0];
|
||||
}
|
||||
|
||||
return new HtmlElement(
|
||||
'pre',
|
||||
[],
|
||||
new HtmlElement('code', $attrs, Xml::escape($block->getStringContent()))
|
||||
);
|
||||
}
|
||||
}
|
||||
43
vendor/league/commonmark/src/Block/Renderer/HeadingRenderer.php
vendored
Normal file
43
vendor/league/commonmark/src/Block/Renderer/HeadingRenderer.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Renderer;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Block\Element\Heading;
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\HtmlElement;
|
||||
|
||||
final class HeadingRenderer implements BlockRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param Heading $block
|
||||
* @param ElementRendererInterface $htmlRenderer
|
||||
* @param bool $inTightList
|
||||
*
|
||||
* @return HtmlElement
|
||||
*/
|
||||
public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, bool $inTightList = false)
|
||||
{
|
||||
if (!($block instanceof Heading)) {
|
||||
throw new \InvalidArgumentException('Incompatible block type: ' . \get_class($block));
|
||||
}
|
||||
|
||||
$tag = 'h' . $block->getLevel();
|
||||
|
||||
$attrs = $block->getData('attributes', []);
|
||||
|
||||
return new HtmlElement($tag, $attrs, $htmlRenderer->renderInlines($block->children()));
|
||||
}
|
||||
}
|
||||
59
vendor/league/commonmark/src/Block/Renderer/HtmlBlockRenderer.php
vendored
Normal file
59
vendor/league/commonmark/src/Block/Renderer/HtmlBlockRenderer.php
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Renderer;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Block\Element\HtmlBlock;
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\EnvironmentInterface;
|
||||
use League\CommonMark\Util\ConfigurationAwareInterface;
|
||||
use League\CommonMark\Util\ConfigurationInterface;
|
||||
|
||||
final class HtmlBlockRenderer implements BlockRendererInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var ConfigurationInterface
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @param HtmlBlock $block
|
||||
* @param ElementRendererInterface $htmlRenderer
|
||||
* @param bool $inTightList
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, bool $inTightList = false)
|
||||
{
|
||||
if (!($block instanceof HtmlBlock)) {
|
||||
throw new \InvalidArgumentException('Incompatible block type: ' . \get_class($block));
|
||||
}
|
||||
|
||||
if ($this->config->get('html_input') === EnvironmentInterface::HTML_INPUT_STRIP) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($this->config->get('html_input') === EnvironmentInterface::HTML_INPUT_ESCAPE) {
|
||||
return \htmlspecialchars($block->getStringContent(), \ENT_NOQUOTES);
|
||||
}
|
||||
|
||||
return $block->getStringContent();
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration)
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
}
|
||||
46
vendor/league/commonmark/src/Block/Renderer/IndentedCodeRenderer.php
vendored
Normal file
46
vendor/league/commonmark/src/Block/Renderer/IndentedCodeRenderer.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Renderer;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Block\Element\IndentedCode;
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\HtmlElement;
|
||||
use League\CommonMark\Util\Xml;
|
||||
|
||||
final class IndentedCodeRenderer implements BlockRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param IndentedCode $block
|
||||
* @param ElementRendererInterface $htmlRenderer
|
||||
* @param bool $inTightList
|
||||
*
|
||||
* @return HtmlElement
|
||||
*/
|
||||
public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, bool $inTightList = false)
|
||||
{
|
||||
if (!($block instanceof IndentedCode)) {
|
||||
throw new \InvalidArgumentException('Incompatible block type: ' . \get_class($block));
|
||||
}
|
||||
|
||||
$attrs = $block->getData('attributes', []);
|
||||
|
||||
return new HtmlElement(
|
||||
'pre',
|
||||
[],
|
||||
new HtmlElement('code', $attrs, Xml::escape($block->getStringContent()))
|
||||
);
|
||||
}
|
||||
}
|
||||
56
vendor/league/commonmark/src/Block/Renderer/ListBlockRenderer.php
vendored
Normal file
56
vendor/league/commonmark/src/Block/Renderer/ListBlockRenderer.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Renderer;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Block\Element\ListBlock;
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\HtmlElement;
|
||||
|
||||
final class ListBlockRenderer implements BlockRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param ListBlock $block
|
||||
* @param ElementRendererInterface $htmlRenderer
|
||||
* @param bool $inTightList
|
||||
*
|
||||
* @return HtmlElement
|
||||
*/
|
||||
public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, bool $inTightList = false)
|
||||
{
|
||||
if (!($block instanceof ListBlock)) {
|
||||
throw new \InvalidArgumentException('Incompatible block type: ' . \get_class($block));
|
||||
}
|
||||
|
||||
$listData = $block->getListData();
|
||||
|
||||
$tag = $listData->type === ListBlock::TYPE_BULLET ? 'ul' : 'ol';
|
||||
|
||||
$attrs = $block->getData('attributes', []);
|
||||
|
||||
if ($listData->start !== null && $listData->start !== 1) {
|
||||
$attrs['start'] = (string) $listData->start;
|
||||
}
|
||||
|
||||
return new HtmlElement(
|
||||
$tag,
|
||||
$attrs,
|
||||
$htmlRenderer->getOption('inner_separator', "\n") . $htmlRenderer->renderBlocks(
|
||||
$block->children(),
|
||||
$block->isTight()
|
||||
) . $htmlRenderer->getOption('inner_separator', "\n")
|
||||
);
|
||||
}
|
||||
}
|
||||
60
vendor/league/commonmark/src/Block/Renderer/ListItemRenderer.php
vendored
Normal file
60
vendor/league/commonmark/src/Block/Renderer/ListItemRenderer.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Renderer;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Block\Element\ListItem;
|
||||
use League\CommonMark\Block\Element\Paragraph;
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\Extension\TaskList\TaskListItemMarker;
|
||||
use League\CommonMark\HtmlElement;
|
||||
|
||||
final class ListItemRenderer implements BlockRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param ListItem $block
|
||||
* @param ElementRendererInterface $htmlRenderer
|
||||
* @param bool $inTightList
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, bool $inTightList = false)
|
||||
{
|
||||
if (!($block instanceof ListItem)) {
|
||||
throw new \InvalidArgumentException('Incompatible block type: ' . \get_class($block));
|
||||
}
|
||||
|
||||
$contents = $htmlRenderer->renderBlocks($block->children(), $inTightList);
|
||||
if (\substr($contents, 0, 1) === '<' && !$this->startsTaskListItem($block)) {
|
||||
$contents = "\n" . $contents;
|
||||
}
|
||||
if (\substr($contents, -1, 1) === '>') {
|
||||
$contents .= "\n";
|
||||
}
|
||||
|
||||
$attrs = $block->getData('attributes', []);
|
||||
|
||||
$li = new HtmlElement('li', $attrs, $contents);
|
||||
|
||||
return $li;
|
||||
}
|
||||
|
||||
private function startsTaskListItem(ListItem $block): bool
|
||||
{
|
||||
$firstChild = $block->firstChild();
|
||||
|
||||
return $firstChild instanceof Paragraph && $firstChild->firstChild() instanceof TaskListItemMarker;
|
||||
}
|
||||
}
|
||||
45
vendor/league/commonmark/src/Block/Renderer/ParagraphRenderer.php
vendored
Normal file
45
vendor/league/commonmark/src/Block/Renderer/ParagraphRenderer.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Renderer;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Block\Element\Paragraph;
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\HtmlElement;
|
||||
|
||||
final class ParagraphRenderer implements BlockRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param Paragraph $block
|
||||
* @param ElementRendererInterface $htmlRenderer
|
||||
* @param bool $inTightList
|
||||
*
|
||||
* @return HtmlElement|string
|
||||
*/
|
||||
public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, bool $inTightList = false)
|
||||
{
|
||||
if (!($block instanceof Paragraph)) {
|
||||
throw new \InvalidArgumentException('Incompatible block type: ' . \get_class($block));
|
||||
}
|
||||
|
||||
if ($inTightList) {
|
||||
return $htmlRenderer->renderInlines($block->children());
|
||||
}
|
||||
|
||||
$attrs = $block->getData('attributes', []);
|
||||
|
||||
return new HtmlElement('p', $attrs, $htmlRenderer->renderInlines($block->children()));
|
||||
}
|
||||
}
|
||||
41
vendor/league/commonmark/src/Block/Renderer/ThematicBreakRenderer.php
vendored
Normal file
41
vendor/league/commonmark/src/Block/Renderer/ThematicBreakRenderer.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Block\Renderer;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Block\Element\ThematicBreak;
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\HtmlElement;
|
||||
|
||||
final class ThematicBreakRenderer implements BlockRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param ThematicBreak $block
|
||||
* @param ElementRendererInterface $htmlRenderer
|
||||
* @param bool $inTightList
|
||||
*
|
||||
* @return HtmlElement
|
||||
*/
|
||||
public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, bool $inTightList = false)
|
||||
{
|
||||
if (!($block instanceof ThematicBreak)) {
|
||||
throw new \InvalidArgumentException('Incompatible block type: ' . \get_class($block));
|
||||
}
|
||||
|
||||
$attrs = $block->getData('attributes', []);
|
||||
|
||||
return new HtmlElement('hr', $attrs, '', true);
|
||||
}
|
||||
}
|
||||
52
vendor/league/commonmark/src/CommonMarkConverter.php
vendored
Normal file
52
vendor/league/commonmark/src/CommonMarkConverter.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark;
|
||||
|
||||
/**
|
||||
* Converts CommonMark-compatible Markdown to HTML.
|
||||
*/
|
||||
class CommonMarkConverter extends MarkdownConverter
|
||||
{
|
||||
/**
|
||||
* The currently-installed version.
|
||||
*
|
||||
* This might be a typical `x.y.z` version, or `x.y-dev`.
|
||||
*
|
||||
* @deprecated in 1.5.0 and will be removed from 2.0.0.
|
||||
* Use \Composer\InstalledVersions provided by composer-runtime-api instead.
|
||||
*/
|
||||
public const VERSION = '1.6.7';
|
||||
|
||||
/**
|
||||
* Create a new commonmark converter instance.
|
||||
*
|
||||
* @param array<string, mixed> $config
|
||||
* @param EnvironmentInterface|null $environment
|
||||
*/
|
||||
public function __construct(array $config = [], EnvironmentInterface $environment = null)
|
||||
{
|
||||
if ($environment === null) {
|
||||
$environment = Environment::createCommonMarkEnvironment();
|
||||
} else {
|
||||
@\trigger_error(\sprintf('Passing an $environment into the "%s" constructor is deprecated in 1.6 and will not be supported in 2.0; use MarkdownConverter instead. See https://commonmark.thephpleague.com/2.0/upgrading/consumers/#commonmarkconverter-and-githubflavoredmarkdownconverter-constructors for more details.', self::class), \E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if ($environment instanceof ConfigurableEnvironmentInterface) {
|
||||
$environment->mergeConfig($config);
|
||||
}
|
||||
|
||||
parent::__construct($environment);
|
||||
}
|
||||
}
|
||||
110
vendor/league/commonmark/src/ConfigurableEnvironmentInterface.php
vendored
Normal file
110
vendor/league/commonmark/src/ConfigurableEnvironmentInterface.php
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark;
|
||||
|
||||
use League\CommonMark\Block\Parser\BlockParserInterface;
|
||||
use League\CommonMark\Block\Renderer\BlockRendererInterface;
|
||||
use League\CommonMark\Delimiter\Processor\DelimiterProcessorInterface;
|
||||
use League\CommonMark\Extension\ExtensionInterface;
|
||||
use League\CommonMark\Inline\Parser\InlineParserInterface;
|
||||
use League\CommonMark\Inline\Renderer\InlineRendererInterface;
|
||||
|
||||
/**
|
||||
* Interface for an Environment which can be configured with config settings, parsers, processors, and renderers
|
||||
*/
|
||||
interface ConfigurableEnvironmentInterface extends EnvironmentInterface
|
||||
{
|
||||
/**
|
||||
* @param array<string, mixed> $config
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function mergeConfig(array $config = []);
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $config
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @deprecated in 1.6 and will be removed in 2.0; use mergeConfig() instead
|
||||
*/
|
||||
public function setConfig(array $config = []);
|
||||
|
||||
/**
|
||||
* Registers the given extension with the Environment
|
||||
*
|
||||
* @param ExtensionInterface $extension
|
||||
*
|
||||
* @return ConfigurableEnvironmentInterface
|
||||
*/
|
||||
public function addExtension(ExtensionInterface $extension): ConfigurableEnvironmentInterface;
|
||||
|
||||
/**
|
||||
* Registers the given block parser with the Environment
|
||||
*
|
||||
* @param BlockParserInterface $parser Block parser instance
|
||||
* @param int $priority Priority (a higher number will be executed earlier)
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function addBlockParser(BlockParserInterface $parser, int $priority = 0): ConfigurableEnvironmentInterface;
|
||||
|
||||
/**
|
||||
* Registers the given inline parser with the Environment
|
||||
*
|
||||
* @param InlineParserInterface $parser Inline parser instance
|
||||
* @param int $priority Priority (a higher number will be executed earlier)
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function addInlineParser(InlineParserInterface $parser, int $priority = 0): ConfigurableEnvironmentInterface;
|
||||
|
||||
/**
|
||||
* Registers the given delimiter processor with the Environment
|
||||
*
|
||||
* @param DelimiterProcessorInterface $processor Delimiter processors instance
|
||||
*
|
||||
* @return ConfigurableEnvironmentInterface
|
||||
*/
|
||||
public function addDelimiterProcessor(DelimiterProcessorInterface $processor): ConfigurableEnvironmentInterface;
|
||||
|
||||
/**
|
||||
* @param string $blockClass The fully-qualified block element class name the renderer below should handle
|
||||
* @param BlockRendererInterface $blockRenderer The renderer responsible for rendering the type of element given above
|
||||
* @param int $priority Priority (a higher number will be executed earlier)
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function addBlockRenderer($blockClass, BlockRendererInterface $blockRenderer, int $priority = 0): ConfigurableEnvironmentInterface;
|
||||
|
||||
/**
|
||||
* Registers the given inline renderer with the Environment
|
||||
*
|
||||
* @param string $inlineClass The fully-qualified inline element class name the renderer below should handle
|
||||
* @param InlineRendererInterface $renderer The renderer responsible for rendering the type of element given above
|
||||
* @param int $priority Priority (a higher number will be executed earlier)
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function addInlineRenderer(string $inlineClass, InlineRendererInterface $renderer, int $priority = 0): ConfigurableEnvironmentInterface;
|
||||
|
||||
/**
|
||||
* Registers the given event listener
|
||||
*
|
||||
* @param string $eventClass Fully-qualified class name of the event this listener should respond to
|
||||
* @param callable $listener Listener to be executed
|
||||
* @param int $priority Priority (a higher number will be executed earlier)
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function addEventListener(string $eventClass, callable $listener, int $priority = 0): ConfigurableEnvironmentInterface;
|
||||
}
|
||||
201
vendor/league/commonmark/src/Context.php
vendored
Normal file
201
vendor/league/commonmark/src/Context.php
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Block\Element\Document;
|
||||
use League\CommonMark\Reference\ReferenceParser;
|
||||
|
||||
/**
|
||||
* Maintains the current state of the Markdown parser engine
|
||||
*/
|
||||
class Context implements ContextInterface
|
||||
{
|
||||
/**
|
||||
* @var EnvironmentInterface
|
||||
*/
|
||||
protected $environment;
|
||||
|
||||
/**
|
||||
* @var Document
|
||||
*/
|
||||
protected $doc;
|
||||
|
||||
/**
|
||||
* @var AbstractBlock|null
|
||||
*/
|
||||
protected $tip;
|
||||
|
||||
/**
|
||||
* @var AbstractBlock
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $lineNumber;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $line;
|
||||
|
||||
/**
|
||||
* @var UnmatchedBlockCloser
|
||||
*/
|
||||
protected $blockCloser;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $blocksParsed = false;
|
||||
|
||||
/**
|
||||
* @var ReferenceParser
|
||||
*/
|
||||
protected $referenceParser;
|
||||
|
||||
public function __construct(Document $document, EnvironmentInterface $environment)
|
||||
{
|
||||
$this->doc = $document;
|
||||
$this->tip = $this->doc;
|
||||
$this->container = $this->doc;
|
||||
|
||||
$this->environment = $environment;
|
||||
|
||||
$this->referenceParser = new ReferenceParser($document->getReferenceMap());
|
||||
|
||||
$this->blockCloser = new UnmatchedBlockCloser($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $line
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setNextLine(string $line)
|
||||
{
|
||||
++$this->lineNumber;
|
||||
$this->line = $line;
|
||||
}
|
||||
|
||||
public function getDocument(): Document
|
||||
{
|
||||
return $this->doc;
|
||||
}
|
||||
|
||||
public function getTip(): ?AbstractBlock
|
||||
{
|
||||
return $this->tip;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AbstractBlock|null $block
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setTip(?AbstractBlock $block)
|
||||
{
|
||||
$this->tip = $block;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLineNumber(): int
|
||||
{
|
||||
return $this->lineNumber;
|
||||
}
|
||||
|
||||
public function getLine(): string
|
||||
{
|
||||
return $this->line;
|
||||
}
|
||||
|
||||
public function getBlockCloser(): UnmatchedBlockCloser
|
||||
{
|
||||
return $this->blockCloser;
|
||||
}
|
||||
|
||||
public function getContainer(): AbstractBlock
|
||||
{
|
||||
return $this->container;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AbstractBlock $container
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setContainer(AbstractBlock $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addBlock(AbstractBlock $block)
|
||||
{
|
||||
$this->blockCloser->closeUnmatchedBlocks();
|
||||
$block->setStartLine($this->lineNumber);
|
||||
|
||||
while ($this->tip !== null && !$this->tip->canContain($block)) {
|
||||
$this->tip->finalize($this, $this->lineNumber);
|
||||
}
|
||||
|
||||
// This should always be true
|
||||
if ($this->tip !== null) {
|
||||
$this->tip->appendChild($block);
|
||||
}
|
||||
|
||||
$this->tip = $block;
|
||||
$this->container = $block;
|
||||
}
|
||||
|
||||
public function replaceContainerBlock(AbstractBlock $replacement)
|
||||
{
|
||||
$this->blockCloser->closeUnmatchedBlocks();
|
||||
$replacement->setStartLine($this->container->getStartLine());
|
||||
$this->container->replaceWith($replacement);
|
||||
|
||||
if ($this->tip === $this->container) {
|
||||
$this->tip = $replacement;
|
||||
}
|
||||
|
||||
$this->container = $replacement;
|
||||
}
|
||||
|
||||
public function getBlocksParsed(): bool
|
||||
{
|
||||
return $this->blocksParsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bool
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setBlocksParsed(bool $bool)
|
||||
{
|
||||
$this->blocksParsed = $bool;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getReferenceParser(): ReferenceParser
|
||||
{
|
||||
return $this->referenceParser;
|
||||
}
|
||||
}
|
||||
99
vendor/league/commonmark/src/ContextInterface.php
vendored
Normal file
99
vendor/league/commonmark/src/ContextInterface.php
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Block\Element\Document;
|
||||
use League\CommonMark\Reference\ReferenceParser;
|
||||
|
||||
interface ContextInterface
|
||||
{
|
||||
/**
|
||||
* @return Document
|
||||
*/
|
||||
public function getDocument(): Document;
|
||||
|
||||
/**
|
||||
* @return AbstractBlock|null
|
||||
*/
|
||||
public function getTip(): ?AbstractBlock;
|
||||
|
||||
/**
|
||||
* @param AbstractBlock|null $block
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setTip(?AbstractBlock $block);
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLineNumber(): int;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLine(): string;
|
||||
|
||||
/**
|
||||
* Finalize and close any unmatched blocks
|
||||
*
|
||||
* @return UnmatchedBlockCloser
|
||||
*/
|
||||
public function getBlockCloser(): UnmatchedBlockCloser;
|
||||
|
||||
/**
|
||||
* @return AbstractBlock
|
||||
*/
|
||||
public function getContainer(): AbstractBlock;
|
||||
|
||||
/**
|
||||
* @param AbstractBlock $container
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setContainer(AbstractBlock $container);
|
||||
|
||||
/**
|
||||
* @param AbstractBlock $block
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addBlock(AbstractBlock $block);
|
||||
|
||||
/**
|
||||
* @param AbstractBlock $replacement
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function replaceContainerBlock(AbstractBlock $replacement);
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getBlocksParsed(): bool;
|
||||
|
||||
/**
|
||||
* @param bool $bool
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setBlocksParsed(bool $bool);
|
||||
|
||||
/**
|
||||
* @return ReferenceParser
|
||||
*/
|
||||
public function getReferenceParser(): ReferenceParser;
|
||||
}
|
||||
84
vendor/league/commonmark/src/Converter.php
vendored
Normal file
84
vendor/league/commonmark/src/Converter.php
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark;
|
||||
|
||||
/**
|
||||
* Converts CommonMark-compatible Markdown to HTML.
|
||||
*
|
||||
* @deprecated This class is deprecated since league/commonmark 1.4, use MarkdownConverter instead.
|
||||
*/
|
||||
class Converter implements ConverterInterface
|
||||
{
|
||||
/**
|
||||
* The document parser instance.
|
||||
*
|
||||
* @var DocParserInterface
|
||||
*/
|
||||
protected $docParser;
|
||||
|
||||
/**
|
||||
* The html renderer instance.
|
||||
*
|
||||
* @var ElementRendererInterface
|
||||
*/
|
||||
protected $htmlRenderer;
|
||||
|
||||
/**
|
||||
* Create a new commonmark converter instance.
|
||||
*
|
||||
* @param DocParserInterface $docParser
|
||||
* @param ElementRendererInterface $htmlRenderer
|
||||
*/
|
||||
public function __construct(DocParserInterface $docParser, ElementRendererInterface $htmlRenderer)
|
||||
{
|
||||
if (!($this instanceof MarkdownConverter)) {
|
||||
@trigger_error(sprintf('The %s class is deprecated since league/commonmark 1.4, use %s instead.', self::class, MarkdownConverter::class), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$this->docParser = $docParser;
|
||||
$this->htmlRenderer = $htmlRenderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts CommonMark to HTML.
|
||||
*
|
||||
* @param string $commonMark
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function convertToHtml(string $commonMark): string
|
||||
{
|
||||
$documentAST = $this->docParser->parse($commonMark);
|
||||
|
||||
return $this->htmlRenderer->renderBlock($documentAST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts CommonMark to HTML.
|
||||
*
|
||||
* @see Converter::convertToHtml
|
||||
*
|
||||
* @param string $commonMark
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __invoke(string $commonMark): string
|
||||
{
|
||||
return $this->convertToHtml($commonMark);
|
||||
}
|
||||
}
|
||||
21
vendor/league/commonmark/src/ConverterInterface.php
vendored
Normal file
21
vendor/league/commonmark/src/ConverterInterface.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark;
|
||||
|
||||
/**
|
||||
* Interface for a service which converts CommonMark to HTML.
|
||||
*
|
||||
* @deprecated ConverterInterface is deprecated since league/commonmark 1.4, use MarkdownConverterInterface instead
|
||||
*/
|
||||
interface ConverterInterface extends MarkdownConverterInterface
|
||||
{
|
||||
}
|
||||
502
vendor/league/commonmark/src/Cursor.php
vendored
Normal file
502
vendor/league/commonmark/src/Cursor.php
vendored
Normal file
@@ -0,0 +1,502 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark;
|
||||
|
||||
use League\CommonMark\Exception\UnexpectedEncodingException;
|
||||
|
||||
class Cursor
|
||||
{
|
||||
public const INDENT_LEVEL = 4;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $line;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $length;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
* It's possible for this to be 1 char past the end, meaning we've parsed all chars and have
|
||||
* reached the end. In this state, any character-returning method MUST return null.
|
||||
*/
|
||||
private $currentPosition = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $column = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $indent = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $previousPosition = 0;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
private $nextNonSpaceCache;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $partiallyConsumedTab = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $lineContainsTabs;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isMultibyte;
|
||||
|
||||
/**
|
||||
* @var array<int, string>
|
||||
*/
|
||||
private $charCache = [];
|
||||
|
||||
/**
|
||||
* @param string $line The line being parsed (ASCII or UTF-8)
|
||||
*/
|
||||
public function __construct(string $line)
|
||||
{
|
||||
if (!\mb_check_encoding($line, 'UTF-8')) {
|
||||
throw new UnexpectedEncodingException('Unexpected encoding - UTF-8 or ASCII was expected');
|
||||
}
|
||||
|
||||
$this->line = $line;
|
||||
$this->length = \mb_strlen($line, 'UTF-8') ?: 0;
|
||||
$this->isMultibyte = $this->length !== \strlen($line);
|
||||
$this->lineContainsTabs = false !== \strpos($line, "\t");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of the next character which is not a space (or tab)
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNextNonSpacePosition(): int
|
||||
{
|
||||
if ($this->nextNonSpaceCache !== null) {
|
||||
return $this->nextNonSpaceCache;
|
||||
}
|
||||
|
||||
$i = $this->currentPosition;
|
||||
$cols = $this->column;
|
||||
|
||||
while (($c = $this->getCharacter($i)) !== null) {
|
||||
if ($c === ' ') {
|
||||
$i++;
|
||||
$cols++;
|
||||
} elseif ($c === "\t") {
|
||||
$i++;
|
||||
$cols += (4 - ($cols % 4));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$nextNonSpace = ($c === null) ? $this->length : $i;
|
||||
$this->indent = $cols - $this->column;
|
||||
|
||||
return $this->nextNonSpaceCache = $nextNonSpace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next character which isn't a space (or tab)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNextNonSpaceCharacter(): ?string
|
||||
{
|
||||
return $this->getCharacter($this->getNextNonSpacePosition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the current indent (number of spaces after current position)
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getIndent(): int
|
||||
{
|
||||
if ($this->nextNonSpaceCache === null) {
|
||||
$this->getNextNonSpacePosition();
|
||||
}
|
||||
|
||||
return $this->indent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the cursor is indented to INDENT_LEVEL
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isIndented(): bool
|
||||
{
|
||||
return $this->getIndent() >= self::INDENT_LEVEL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|null $index
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCharacter(?int $index = null): ?string
|
||||
{
|
||||
if ($index === null) {
|
||||
$index = $this->currentPosition;
|
||||
}
|
||||
|
||||
// Index out-of-bounds, or we're at the end
|
||||
if ($index < 0 || $index >= $this->length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->isMultibyte) {
|
||||
if (isset($this->charCache[$index])) {
|
||||
return $this->charCache[$index];
|
||||
}
|
||||
|
||||
return $this->charCache[$index] = \mb_substr($this->line, $index, 1, 'UTF-8');
|
||||
}
|
||||
|
||||
return $this->line[$index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next character (or null, if none) without advancing forwards
|
||||
*
|
||||
* @param int $offset
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function peek(int $offset = 1): ?string
|
||||
{
|
||||
return $this->getCharacter($this->currentPosition + $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the remainder is blank
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isBlank(): bool
|
||||
{
|
||||
return $this->nextNonSpaceCache === $this->length || $this->getNextNonSpacePosition() === $this->length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the cursor forwards
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function advance()
|
||||
{
|
||||
$this->advanceBy(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the cursor forwards
|
||||
*
|
||||
* @param int $characters Number of characters to advance by
|
||||
* @param bool $advanceByColumns Whether to advance by columns instead of spaces
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function advanceBy(int $characters, bool $advanceByColumns = false)
|
||||
{
|
||||
if ($characters === 0) {
|
||||
$this->previousPosition = $this->currentPosition;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->previousPosition = $this->currentPosition;
|
||||
$this->nextNonSpaceCache = null;
|
||||
|
||||
// Optimization to avoid tab handling logic if we have no tabs
|
||||
if (!$this->lineContainsTabs || false === \strpos(
|
||||
$nextFewChars = $this->isMultibyte ?
|
||||
\mb_substr($this->line, $this->currentPosition, $characters, 'UTF-8') :
|
||||
\substr($this->line, $this->currentPosition, $characters),
|
||||
"\t"
|
||||
)) {
|
||||
$length = \min($characters, $this->length - $this->currentPosition);
|
||||
$this->partiallyConsumedTab = false;
|
||||
$this->currentPosition += $length;
|
||||
$this->column += $length;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($characters === 1 && !empty($nextFewChars)) {
|
||||
$asArray = [$nextFewChars];
|
||||
} elseif ($this->isMultibyte) {
|
||||
/** @var string[] $asArray */
|
||||
$asArray = \preg_split('//u', $nextFewChars, -1, \PREG_SPLIT_NO_EMPTY);
|
||||
} else {
|
||||
$asArray = \str_split($nextFewChars);
|
||||
}
|
||||
|
||||
foreach ($asArray as $relPos => $c) {
|
||||
if ($c === "\t") {
|
||||
$charsToTab = 4 - ($this->column % 4);
|
||||
if ($advanceByColumns) {
|
||||
$this->partiallyConsumedTab = $charsToTab > $characters;
|
||||
$charsToAdvance = $charsToTab > $characters ? $characters : $charsToTab;
|
||||
$this->column += $charsToAdvance;
|
||||
$this->currentPosition += $this->partiallyConsumedTab ? 0 : 1;
|
||||
$characters -= $charsToAdvance;
|
||||
} else {
|
||||
$this->partiallyConsumedTab = false;
|
||||
$this->column += $charsToTab;
|
||||
$this->currentPosition++;
|
||||
$characters--;
|
||||
}
|
||||
} else {
|
||||
$this->partiallyConsumedTab = false;
|
||||
$this->currentPosition++;
|
||||
$this->column++;
|
||||
$characters--;
|
||||
}
|
||||
|
||||
if ($characters <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances the cursor by a single space or tab, if present
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function advanceBySpaceOrTab(): bool
|
||||
{
|
||||
$character = $this->getCharacter();
|
||||
|
||||
if ($character === ' ' || $character === "\t") {
|
||||
$this->advanceBy(1, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse zero or more space/tab characters
|
||||
*
|
||||
* @return int Number of positions moved
|
||||
*/
|
||||
public function advanceToNextNonSpaceOrTab(): int
|
||||
{
|
||||
$newPosition = $this->getNextNonSpacePosition();
|
||||
$this->advanceBy($newPosition - $this->currentPosition);
|
||||
$this->partiallyConsumedTab = false;
|
||||
|
||||
return $this->currentPosition - $this->previousPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse zero or more space characters, including at most one newline.
|
||||
*
|
||||
* Tab characters are not parsed with this function.
|
||||
*
|
||||
* @return int Number of positions moved
|
||||
*/
|
||||
public function advanceToNextNonSpaceOrNewline(): int
|
||||
{
|
||||
$remainder = $this->getRemainder();
|
||||
|
||||
// Optimization: Avoid the regex if we know there are no spaces or newlines
|
||||
if (empty($remainder) || ($remainder[0] !== ' ' && $remainder[0] !== "\n")) {
|
||||
$this->previousPosition = $this->currentPosition;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
$matches = [];
|
||||
\preg_match('/^ *(?:\n *)?/', $remainder, $matches, \PREG_OFFSET_CAPTURE);
|
||||
|
||||
// [0][0] contains the matched text
|
||||
// [0][1] contains the index of that match
|
||||
$increment = $matches[0][1] + \strlen($matches[0][0]);
|
||||
|
||||
$this->advanceBy($increment);
|
||||
|
||||
return $this->currentPosition - $this->previousPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the position to the very end of the line
|
||||
*
|
||||
* @return int The number of characters moved
|
||||
*/
|
||||
public function advanceToEnd(): int
|
||||
{
|
||||
$this->previousPosition = $this->currentPosition;
|
||||
$this->nextNonSpaceCache = null;
|
||||
|
||||
$this->currentPosition = $this->length;
|
||||
|
||||
return $this->currentPosition - $this->previousPosition;
|
||||
}
|
||||
|
||||
public function getRemainder(): string
|
||||
{
|
||||
if ($this->currentPosition >= $this->length) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$prefix = '';
|
||||
$position = $this->currentPosition;
|
||||
if ($this->partiallyConsumedTab) {
|
||||
$position++;
|
||||
$charsToTab = 4 - ($this->column % 4);
|
||||
$prefix = \str_repeat(' ', $charsToTab);
|
||||
}
|
||||
|
||||
$subString = $this->isMultibyte ?
|
||||
\mb_substr($this->line, $position, null, 'UTF-8') :
|
||||
\substr($this->line, $position);
|
||||
|
||||
return $prefix . $subString;
|
||||
}
|
||||
|
||||
public function getLine(): string
|
||||
{
|
||||
return $this->line;
|
||||
}
|
||||
|
||||
public function isAtEnd(): bool
|
||||
{
|
||||
return $this->currentPosition >= $this->length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to match a regular expression
|
||||
*
|
||||
* Returns the matching text and advances to the end of that match
|
||||
*
|
||||
* @param string $regex
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function match(string $regex): ?string
|
||||
{
|
||||
$subject = $this->getRemainder();
|
||||
|
||||
if (!\preg_match($regex, $subject, $matches, \PREG_OFFSET_CAPTURE)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// $matches[0][0] contains the matched text
|
||||
// $matches[0][1] contains the index of that match
|
||||
|
||||
if ($this->isMultibyte) {
|
||||
// PREG_OFFSET_CAPTURE always returns the byte offset, not the char offset, which is annoying
|
||||
$offset = \mb_strlen(\substr($subject, 0, $matches[0][1]), 'UTF-8');
|
||||
$matchLength = \mb_strlen($matches[0][0], 'UTF-8');
|
||||
} else {
|
||||
$offset = $matches[0][1];
|
||||
$matchLength = \strlen($matches[0][0]);
|
||||
}
|
||||
|
||||
// [0][0] contains the matched text
|
||||
// [0][1] contains the index of that match
|
||||
$this->advanceBy($offset + $matchLength);
|
||||
|
||||
return $matches[0][0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Encapsulates the current state of this cursor in case you need to rollback later.
|
||||
*
|
||||
* WARNING: Do not parse or use the return value for ANYTHING except for
|
||||
* passing it back into restoreState(), as the number of values and their
|
||||
* contents may change in any future release without warning.
|
||||
*
|
||||
* @return array<mixed>
|
||||
*/
|
||||
public function saveState()
|
||||
{
|
||||
return [
|
||||
$this->currentPosition,
|
||||
$this->previousPosition,
|
||||
$this->nextNonSpaceCache,
|
||||
$this->indent,
|
||||
$this->column,
|
||||
$this->partiallyConsumedTab,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the cursor to a previous state.
|
||||
*
|
||||
* Pass in the value previously obtained by calling saveState().
|
||||
*
|
||||
* @param array<mixed> $state
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function restoreState($state)
|
||||
{
|
||||
list(
|
||||
$this->currentPosition,
|
||||
$this->previousPosition,
|
||||
$this->nextNonSpaceCache,
|
||||
$this->indent,
|
||||
$this->column,
|
||||
$this->partiallyConsumedTab,
|
||||
) = $state;
|
||||
}
|
||||
|
||||
public function getPosition(): int
|
||||
{
|
||||
return $this->currentPosition;
|
||||
}
|
||||
|
||||
public function getPreviousText(): string
|
||||
{
|
||||
return \mb_substr($this->line, $this->previousPosition, $this->currentPosition - $this->previousPosition, 'UTF-8');
|
||||
}
|
||||
|
||||
public function getSubstring(int $start, ?int $length = null): string
|
||||
{
|
||||
if ($this->isMultibyte) {
|
||||
return \mb_substr($this->line, $start, $length, 'UTF-8');
|
||||
} elseif ($length !== null) {
|
||||
return \substr($this->line, $start, $length);
|
||||
}
|
||||
|
||||
return \substr($this->line, $start);
|
||||
}
|
||||
|
||||
public function getColumn(): int
|
||||
{
|
||||
return $this->column;
|
||||
}
|
||||
}
|
||||
152
vendor/league/commonmark/src/Delimiter/Delimiter.php
vendored
Normal file
152
vendor/league/commonmark/src/Delimiter/Delimiter.php
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Delimiter;
|
||||
|
||||
use League\CommonMark\Inline\Element\AbstractStringContainer;
|
||||
|
||||
final class Delimiter implements DelimiterInterface
|
||||
{
|
||||
/** @var string */
|
||||
private $char;
|
||||
|
||||
/** @var int */
|
||||
private $length;
|
||||
|
||||
/** @var int */
|
||||
private $originalLength;
|
||||
|
||||
/** @var AbstractStringContainer */
|
||||
private $inlineNode;
|
||||
|
||||
/** @var DelimiterInterface|null */
|
||||
private $previous;
|
||||
|
||||
/** @var DelimiterInterface|null */
|
||||
private $next;
|
||||
|
||||
/** @var bool */
|
||||
private $canOpen;
|
||||
|
||||
/** @var bool */
|
||||
private $canClose;
|
||||
|
||||
/** @var bool */
|
||||
private $active;
|
||||
|
||||
/** @var int|null */
|
||||
private $index;
|
||||
|
||||
/**
|
||||
* @param string $char
|
||||
* @param int $numDelims
|
||||
* @param AbstractStringContainer $node
|
||||
* @param bool $canOpen
|
||||
* @param bool $canClose
|
||||
* @param int|null $index
|
||||
*/
|
||||
public function __construct(string $char, int $numDelims, AbstractStringContainer $node, bool $canOpen, bool $canClose, ?int $index = null)
|
||||
{
|
||||
$this->char = $char;
|
||||
$this->length = $numDelims;
|
||||
$this->originalLength = $numDelims;
|
||||
$this->inlineNode = $node;
|
||||
$this->canOpen = $canOpen;
|
||||
$this->canClose = $canClose;
|
||||
$this->active = true;
|
||||
$this->index = $index;
|
||||
}
|
||||
|
||||
public function canClose(): bool
|
||||
{
|
||||
return $this->canClose;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $canClose
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setCanClose(bool $canClose)
|
||||
{
|
||||
$this->canClose = $canClose;
|
||||
}
|
||||
|
||||
public function canOpen(): bool
|
||||
{
|
||||
return $this->canOpen;
|
||||
}
|
||||
|
||||
public function isActive(): bool
|
||||
{
|
||||
return $this->active;
|
||||
}
|
||||
|
||||
public function setActive(bool $active)
|
||||
{
|
||||
$this->active = $active;
|
||||
}
|
||||
|
||||
public function getChar(): string
|
||||
{
|
||||
return $this->char;
|
||||
}
|
||||
|
||||
public function getIndex(): ?int
|
||||
{
|
||||
return $this->index;
|
||||
}
|
||||
|
||||
public function getNext(): ?DelimiterInterface
|
||||
{
|
||||
return $this->next;
|
||||
}
|
||||
|
||||
public function setNext(?DelimiterInterface $next)
|
||||
{
|
||||
$this->next = $next;
|
||||
}
|
||||
|
||||
public function getLength(): int
|
||||
{
|
||||
return $this->length;
|
||||
}
|
||||
|
||||
public function setLength(int $length)
|
||||
{
|
||||
$this->length = $length;
|
||||
}
|
||||
|
||||
public function getOriginalLength(): int
|
||||
{
|
||||
return $this->originalLength;
|
||||
}
|
||||
|
||||
public function getInlineNode(): AbstractStringContainer
|
||||
{
|
||||
return $this->inlineNode;
|
||||
}
|
||||
|
||||
public function getPrevious(): ?DelimiterInterface
|
||||
{
|
||||
return $this->previous;
|
||||
}
|
||||
|
||||
public function setPrevious(?DelimiterInterface $previous): DelimiterInterface
|
||||
{
|
||||
$this->previous = $previous;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
71
vendor/league/commonmark/src/Delimiter/DelimiterInterface.php
vendored
Normal file
71
vendor/league/commonmark/src/Delimiter/DelimiterInterface.php
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Delimiter;
|
||||
|
||||
use League\CommonMark\Inline\Element\AbstractStringContainer;
|
||||
|
||||
interface DelimiterInterface
|
||||
{
|
||||
public function canClose(): bool;
|
||||
|
||||
public function canOpen(): bool;
|
||||
|
||||
public function isActive(): bool;
|
||||
|
||||
/**
|
||||
* @param bool $active
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setActive(bool $active);
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getChar(): string;
|
||||
|
||||
public function getIndex(): ?int;
|
||||
|
||||
public function getNext(): ?DelimiterInterface;
|
||||
|
||||
/**
|
||||
* @param DelimiterInterface|null $next
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setNext(?DelimiterInterface $next);
|
||||
|
||||
public function getLength(): int;
|
||||
|
||||
/**
|
||||
* @param int $length
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setLength(int $length);
|
||||
|
||||
public function getOriginalLength(): int;
|
||||
|
||||
public function getInlineNode(): AbstractStringContainer;
|
||||
|
||||
public function getPrevious(): ?DelimiterInterface;
|
||||
|
||||
/**
|
||||
* @param DelimiterInterface|null $previous
|
||||
*
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function setPrevious(?DelimiterInterface $previous);
|
||||
}
|
||||
234
vendor/league/commonmark/src/Delimiter/DelimiterStack.php
vendored
Normal file
234
vendor/league/commonmark/src/Delimiter/DelimiterStack.php
vendored
Normal file
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* Additional emphasis processing code based on commonmark-java (https://github.com/atlassian/commonmark-java)
|
||||
* - (c) Atlassian Pty Ltd
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Delimiter;
|
||||
|
||||
use League\CommonMark\Delimiter\Processor\DelimiterProcessorCollection;
|
||||
use League\CommonMark\Inline\AdjacentTextMerger;
|
||||
|
||||
final class DelimiterStack
|
||||
{
|
||||
/**
|
||||
* @var DelimiterInterface|null
|
||||
*/
|
||||
private $top;
|
||||
|
||||
/**
|
||||
* @param DelimiterInterface $newDelimiter
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function push(DelimiterInterface $newDelimiter)
|
||||
{
|
||||
$newDelimiter->setPrevious($this->top);
|
||||
|
||||
if ($this->top !== null) {
|
||||
$this->top->setNext($newDelimiter);
|
||||
}
|
||||
|
||||
$this->top = $newDelimiter;
|
||||
}
|
||||
|
||||
private function findEarliest(DelimiterInterface $stackBottom = null): ?DelimiterInterface
|
||||
{
|
||||
$delimiter = $this->top;
|
||||
while ($delimiter !== null && $delimiter->getPrevious() !== $stackBottom) {
|
||||
$delimiter = $delimiter->getPrevious();
|
||||
}
|
||||
|
||||
return $delimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DelimiterInterface $delimiter
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function removeDelimiter(DelimiterInterface $delimiter)
|
||||
{
|
||||
if ($delimiter->getPrevious() !== null) {
|
||||
$delimiter->getPrevious()->setNext($delimiter->getNext());
|
||||
}
|
||||
|
||||
if ($delimiter->getNext() === null) {
|
||||
// top of stack
|
||||
$this->top = $delimiter->getPrevious();
|
||||
} else {
|
||||
$delimiter->getNext()->setPrevious($delimiter->getPrevious());
|
||||
}
|
||||
}
|
||||
|
||||
private function removeDelimiterAndNode(DelimiterInterface $delimiter): void
|
||||
{
|
||||
$delimiter->getInlineNode()->detach();
|
||||
$this->removeDelimiter($delimiter);
|
||||
}
|
||||
|
||||
private function removeDelimitersBetween(DelimiterInterface $opener, DelimiterInterface $closer): void
|
||||
{
|
||||
$delimiter = $closer->getPrevious();
|
||||
while ($delimiter !== null && $delimiter !== $opener) {
|
||||
$previous = $delimiter->getPrevious();
|
||||
$this->removeDelimiter($delimiter);
|
||||
$delimiter = $previous;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DelimiterInterface|null $stackBottom
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function removeAll(DelimiterInterface $stackBottom = null)
|
||||
{
|
||||
while ($this->top && $this->top !== $stackBottom) {
|
||||
$this->removeDelimiter($this->top);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $character
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function removeEarlierMatches(string $character)
|
||||
{
|
||||
$opener = $this->top;
|
||||
while ($opener !== null) {
|
||||
if ($opener->getChar() === $character) {
|
||||
$opener->setActive(false);
|
||||
}
|
||||
|
||||
$opener = $opener->getPrevious();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $characters
|
||||
*
|
||||
* @return DelimiterInterface|null
|
||||
*/
|
||||
public function searchByCharacter($characters): ?DelimiterInterface
|
||||
{
|
||||
if (!\is_array($characters)) {
|
||||
$characters = [$characters];
|
||||
}
|
||||
|
||||
$opener = $this->top;
|
||||
while ($opener !== null) {
|
||||
if (\in_array($opener->getChar(), $characters)) {
|
||||
break;
|
||||
}
|
||||
$opener = $opener->getPrevious();
|
||||
}
|
||||
|
||||
return $opener;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DelimiterInterface|null $stackBottom
|
||||
* @param DelimiterProcessorCollection $processors
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function processDelimiters(?DelimiterInterface $stackBottom, DelimiterProcessorCollection $processors)
|
||||
{
|
||||
$openersBottom = [];
|
||||
|
||||
// Find first closer above stackBottom
|
||||
$closer = $this->findEarliest($stackBottom);
|
||||
|
||||
// Move forward, looking for closers, and handling each
|
||||
while ($closer !== null) {
|
||||
$delimiterChar = $closer->getChar();
|
||||
|
||||
$delimiterProcessor = $processors->getDelimiterProcessor($delimiterChar);
|
||||
if (!$closer->canClose() || $delimiterProcessor === null) {
|
||||
$closer = $closer->getNext();
|
||||
continue;
|
||||
}
|
||||
|
||||
$openingDelimiterChar = $delimiterProcessor->getOpeningCharacter();
|
||||
|
||||
$useDelims = 0;
|
||||
$openerFound = false;
|
||||
$potentialOpenerFound = false;
|
||||
$opener = $closer->getPrevious();
|
||||
while ($opener !== null && $opener !== $stackBottom && $opener !== ($openersBottom[$delimiterChar] ?? null)) {
|
||||
if ($opener->canOpen() && $opener->getChar() === $openingDelimiterChar) {
|
||||
$potentialOpenerFound = true;
|
||||
$useDelims = $delimiterProcessor->getDelimiterUse($opener, $closer);
|
||||
if ($useDelims > 0) {
|
||||
$openerFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$opener = $opener->getPrevious();
|
||||
}
|
||||
|
||||
if (!$openerFound) {
|
||||
if (!$potentialOpenerFound) {
|
||||
// Only do this when we didn't even have a potential
|
||||
// opener (one that matches the character and can open).
|
||||
// If an opener was rejected because of the number of
|
||||
// delimiters (e.g. because of the "multiple of 3"
|
||||
// Set lower bound for future searches for openersrule),
|
||||
// we want to consider it next time because the number
|
||||
// of delimiters can change as we continue processing.
|
||||
$openersBottom[$delimiterChar] = $closer->getPrevious();
|
||||
if (!$closer->canOpen()) {
|
||||
// We can remove a closer that can't be an opener,
|
||||
// once we've seen there's no matching opener.
|
||||
$this->removeDelimiter($closer);
|
||||
}
|
||||
}
|
||||
$closer = $closer->getNext();
|
||||
continue;
|
||||
}
|
||||
|
||||
$openerNode = $opener->getInlineNode();
|
||||
$closerNode = $closer->getInlineNode();
|
||||
|
||||
// Remove number of used delimiters from stack and inline nodes.
|
||||
$opener->setLength($opener->getLength() - $useDelims);
|
||||
$closer->setLength($closer->getLength() - $useDelims);
|
||||
|
||||
$openerNode->setContent(\substr($openerNode->getContent(), 0, -$useDelims));
|
||||
$closerNode->setContent(\substr($closerNode->getContent(), 0, -$useDelims));
|
||||
|
||||
$this->removeDelimitersBetween($opener, $closer);
|
||||
// The delimiter processor can re-parent the nodes between opener and closer,
|
||||
// so make sure they're contiguous already. Exclusive because we want to keep opener/closer themselves.
|
||||
AdjacentTextMerger::mergeTextNodesBetweenExclusive($openerNode, $closerNode);
|
||||
$delimiterProcessor->process($openerNode, $closerNode, $useDelims);
|
||||
|
||||
// No delimiter characters left to process, so we can remove delimiter and the now empty node.
|
||||
if ($opener->getLength() === 0) {
|
||||
$this->removeDelimiterAndNode($opener);
|
||||
}
|
||||
|
||||
if ($closer->getLength() === 0) {
|
||||
$next = $closer->getNext();
|
||||
$this->removeDelimiterAndNode($closer);
|
||||
$closer = $next;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all delimiters
|
||||
$this->removeAll($stackBottom);
|
||||
}
|
||||
}
|
||||
73
vendor/league/commonmark/src/Delimiter/Processor/DelimiterProcessorCollection.php
vendored
Normal file
73
vendor/league/commonmark/src/Delimiter/Processor/DelimiterProcessorCollection.php
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* Additional emphasis processing code based on commonmark-java (https://github.com/atlassian/commonmark-java)
|
||||
* - (c) Atlassian Pty Ltd
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Delimiter\Processor;
|
||||
|
||||
final class DelimiterProcessorCollection implements DelimiterProcessorCollectionInterface
|
||||
{
|
||||
/** @var array<string,DelimiterProcessorInterface>|DelimiterProcessorInterface[] */
|
||||
private $processorsByChar = [];
|
||||
|
||||
public function add(DelimiterProcessorInterface $processor)
|
||||
{
|
||||
$opening = $processor->getOpeningCharacter();
|
||||
$closing = $processor->getClosingCharacter();
|
||||
|
||||
if ($opening === $closing) {
|
||||
$old = $this->processorsByChar[$opening] ?? null;
|
||||
if ($old !== null && $old->getOpeningCharacter() === $old->getClosingCharacter()) {
|
||||
$this->addStaggeredDelimiterProcessorForChar($opening, $old, $processor);
|
||||
} else {
|
||||
$this->addDelimiterProcessorForChar($opening, $processor);
|
||||
}
|
||||
} else {
|
||||
$this->addDelimiterProcessorForChar($opening, $processor);
|
||||
$this->addDelimiterProcessorForChar($closing, $processor);
|
||||
}
|
||||
}
|
||||
|
||||
public function getDelimiterProcessor(string $char): ?DelimiterProcessorInterface
|
||||
{
|
||||
return $this->processorsByChar[$char] ?? null;
|
||||
}
|
||||
|
||||
public function getDelimiterCharacters(): array
|
||||
{
|
||||
return \array_keys($this->processorsByChar);
|
||||
}
|
||||
|
||||
private function addDelimiterProcessorForChar(string $delimiterChar, DelimiterProcessorInterface $processor): void
|
||||
{
|
||||
if (isset($this->processorsByChar[$delimiterChar])) {
|
||||
throw new \InvalidArgumentException(\sprintf('Delim processor for character "%s" already exists', $processor->getOpeningCharacter()));
|
||||
}
|
||||
|
||||
$this->processorsByChar[$delimiterChar] = $processor;
|
||||
}
|
||||
|
||||
private function addStaggeredDelimiterProcessorForChar(string $opening, DelimiterProcessorInterface $old, DelimiterProcessorInterface $new): void
|
||||
{
|
||||
if ($old instanceof StaggeredDelimiterProcessor) {
|
||||
$s = $old;
|
||||
} else {
|
||||
$s = new StaggeredDelimiterProcessor($opening, $old);
|
||||
}
|
||||
|
||||
$s->add($new);
|
||||
$this->processorsByChar[$opening] = $s;
|
||||
}
|
||||
}
|
||||
48
vendor/league/commonmark/src/Delimiter/Processor/DelimiterProcessorCollectionInterface.php
vendored
Normal file
48
vendor/league/commonmark/src/Delimiter/Processor/DelimiterProcessorCollectionInterface.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* Additional emphasis processing code based on commonmark-java (https://github.com/atlassian/commonmark-java)
|
||||
* - (c) Atlassian Pty Ltd
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Delimiter\Processor;
|
||||
|
||||
interface DelimiterProcessorCollectionInterface
|
||||
{
|
||||
/**
|
||||
* Add the given delim processor to the collection
|
||||
*
|
||||
* @param DelimiterProcessorInterface $processor The delim processor to add
|
||||
*
|
||||
* @throws \InvalidArgumentException Exception will be thrown if attempting to add multiple processors for the same character
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add(DelimiterProcessorInterface $processor);
|
||||
|
||||
/**
|
||||
* Returns the delim processor which handles the given character if one exists
|
||||
*
|
||||
* @param string $char
|
||||
*
|
||||
* @return DelimiterProcessorInterface|null
|
||||
*/
|
||||
public function getDelimiterProcessor(string $char): ?DelimiterProcessorInterface;
|
||||
|
||||
/**
|
||||
* Returns an array of delimiter characters who have associated processors
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getDelimiterCharacters(): array;
|
||||
}
|
||||
86
vendor/league/commonmark/src/Delimiter/Processor/DelimiterProcessorInterface.php
vendored
Normal file
86
vendor/league/commonmark/src/Delimiter/Processor/DelimiterProcessorInterface.php
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* Additional emphasis processing code based on commonmark-java (https://github.com/atlassian/commonmark-java)
|
||||
* - (c) Atlassian Pty Ltd
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Delimiter\Processor;
|
||||
|
||||
use League\CommonMark\Delimiter\DelimiterInterface;
|
||||
use League\CommonMark\Inline\Element\AbstractStringContainer;
|
||||
|
||||
/**
|
||||
* Interface for a delimiter processor
|
||||
*/
|
||||
interface DelimiterProcessorInterface
|
||||
{
|
||||
/**
|
||||
* Returns the character that marks the beginning of a delimited node.
|
||||
*
|
||||
* This must not clash with any other processors being added to the environment.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOpeningCharacter(): string;
|
||||
|
||||
/**
|
||||
* Returns the character that marks the ending of a delimited node.
|
||||
*
|
||||
* This must not clash with any other processors being added to the environment.
|
||||
*
|
||||
* Note that for a symmetric delimiter such as "*", this is the same as the opening.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getClosingCharacter(): string;
|
||||
|
||||
/**
|
||||
* Minimum number of delimiter characters that are needed to active this.
|
||||
*
|
||||
* Must be at least 1.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getMinLength(): int;
|
||||
|
||||
/**
|
||||
* Determine how many (if any) of the delimiter characters should be used.
|
||||
*
|
||||
* This allows implementations to decide how many characters to be used
|
||||
* based on the properties of the delimiter runs. An implementation can also
|
||||
* return 0 when it doesn't want to allow this particular combination of
|
||||
* delimiter runs.
|
||||
*
|
||||
* @param DelimiterInterface $opener The opening delimiter run
|
||||
* @param DelimiterInterface $closer The closing delimiter run
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getDelimiterUse(DelimiterInterface $opener, DelimiterInterface $closer): int;
|
||||
|
||||
/**
|
||||
* Process the matched delimiters, e.g. by wrapping the nodes between opener
|
||||
* and closer in a new node, or appending a new node after the opener.
|
||||
*
|
||||
* Note that removal of the delimiter from the delimiter nodes and detaching
|
||||
* them is done by the caller.
|
||||
*
|
||||
* @param AbstractStringContainer $opener The node that contained the opening delimiter
|
||||
* @param AbstractStringContainer $closer The node that contained the closing delimiter
|
||||
* @param int $delimiterUse The number of delimiters that were used
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(AbstractStringContainer $opener, AbstractStringContainer $closer, int $delimiterUse);
|
||||
}
|
||||
137
vendor/league/commonmark/src/Delimiter/Processor/EmphasisDelimiterProcessor.php
vendored
Normal file
137
vendor/league/commonmark/src/Delimiter/Processor/EmphasisDelimiterProcessor.php
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* Additional emphasis processing code based on commonmark-java (https://github.com/atlassian/commonmark-java)
|
||||
* - (c) Atlassian Pty Ltd
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Delimiter\Processor;
|
||||
|
||||
use League\CommonMark\Delimiter\DelimiterInterface;
|
||||
use League\CommonMark\Inline\Element\AbstractStringContainer;
|
||||
use League\CommonMark\Inline\Element\Emphasis;
|
||||
use League\CommonMark\Inline\Element\Strong;
|
||||
use League\CommonMark\Util\ConfigurationAwareInterface;
|
||||
use League\CommonMark\Util\ConfigurationInterface;
|
||||
|
||||
final class EmphasisDelimiterProcessor implements DelimiterProcessorInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @var string */
|
||||
private $char;
|
||||
|
||||
/** @var ConfigurationInterface|null */
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @param string $char The emphasis character to use (typically '*' or '_')
|
||||
*/
|
||||
public function __construct(string $char)
|
||||
{
|
||||
$this->char = $char;
|
||||
}
|
||||
|
||||
public function getOpeningCharacter(): string
|
||||
{
|
||||
return $this->char;
|
||||
}
|
||||
|
||||
public function getClosingCharacter(): string
|
||||
{
|
||||
return $this->char;
|
||||
}
|
||||
|
||||
public function getMinLength(): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function getDelimiterUse(DelimiterInterface $opener, DelimiterInterface $closer): int
|
||||
{
|
||||
// "Multiple of 3" rule for internal delimiter runs
|
||||
if (($opener->canClose() || $closer->canOpen()) && $closer->getOriginalLength() % 3 !== 0 && ($opener->getOriginalLength() + $closer->getOriginalLength()) % 3 === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate actual number of delimiters used from this closer
|
||||
if ($opener->getLength() >= 2 && $closer->getLength() >= 2) {
|
||||
if ($this->enableStrong()) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($this->enableEm()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function process(AbstractStringContainer $opener, AbstractStringContainer $closer, int $delimiterUse)
|
||||
{
|
||||
if ($delimiterUse === 1) {
|
||||
$emphasis = new Emphasis();
|
||||
} elseif ($delimiterUse === 2) {
|
||||
$emphasis = new Strong();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
$next = $opener->next();
|
||||
while ($next !== null && $next !== $closer) {
|
||||
$tmp = $next->next();
|
||||
$emphasis->appendChild($next);
|
||||
$next = $tmp;
|
||||
}
|
||||
|
||||
$opener->insertAfter($emphasis);
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration)
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
|
||||
private function enableStrong(): bool
|
||||
{
|
||||
if ($this->config === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$deprecatedEnableStrong = $this->config->get('enable_strong', ConfigurationInterface::MISSING);
|
||||
if ($deprecatedEnableStrong !== ConfigurationInterface::MISSING) {
|
||||
@\trigger_error('The "enable_strong" configuration option is deprecated in league/commonmark 1.6 and will be replaced with "commonmark > enable_strong" in 2.0', \E_USER_DEPRECATED);
|
||||
} else {
|
||||
$deprecatedEnableStrong = true;
|
||||
}
|
||||
|
||||
return $this->config->get('commonmark/enable_strong', $deprecatedEnableStrong);
|
||||
}
|
||||
|
||||
private function enableEm(): bool
|
||||
{
|
||||
if ($this->config === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$deprecatedEnableEm = $this->config->get('enable_em', ConfigurationInterface::MISSING);
|
||||
if ($deprecatedEnableEm !== ConfigurationInterface::MISSING) {
|
||||
@\trigger_error('The "enable_em" configuration option is deprecated in league/commonmark 1.6 and will be replaced with "commonmark > enable_em" in 2.0', \E_USER_DEPRECATED);
|
||||
} else {
|
||||
$deprecatedEnableEm = true;
|
||||
}
|
||||
|
||||
return $this->config->get('commonmark/enable_em', $deprecatedEnableEm);
|
||||
}
|
||||
}
|
||||
106
vendor/league/commonmark/src/Delimiter/Processor/StaggeredDelimiterProcessor.php
vendored
Normal file
106
vendor/league/commonmark/src/Delimiter/Processor/StaggeredDelimiterProcessor.php
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Additional emphasis processing code based on commonmark-java (https://github.com/atlassian/commonmark-java)
|
||||
* - (c) Atlassian Pty Ltd
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Delimiter\Processor;
|
||||
|
||||
use League\CommonMark\Delimiter\DelimiterInterface;
|
||||
use League\CommonMark\Inline\Element\AbstractStringContainer;
|
||||
|
||||
/**
|
||||
* An implementation of DelimiterProcessorInterface that dispatches all calls to two or more other DelimiterProcessors
|
||||
* depending on the length of the delimiter run. All child DelimiterProcessors must have different minimum
|
||||
* lengths. A given delimiter run is dispatched to the child with the largest acceptable minimum length. If no
|
||||
* child is applicable, the one with the largest minimum length is chosen.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class StaggeredDelimiterProcessor implements DelimiterProcessorInterface
|
||||
{
|
||||
/** @var string */
|
||||
private $delimiterChar;
|
||||
|
||||
/** @var int */
|
||||
private $minLength = 0;
|
||||
|
||||
/** @var array<int, DelimiterProcessorInterface>|DelimiterProcessorInterface[] */
|
||||
private $processors = []; // keyed by minLength in reverse order
|
||||
|
||||
public function __construct(string $char, DelimiterProcessorInterface $processor)
|
||||
{
|
||||
$this->delimiterChar = $char;
|
||||
$this->add($processor);
|
||||
}
|
||||
|
||||
public function getOpeningCharacter(): string
|
||||
{
|
||||
return $this->delimiterChar;
|
||||
}
|
||||
|
||||
public function getClosingCharacter(): string
|
||||
{
|
||||
return $this->delimiterChar;
|
||||
}
|
||||
|
||||
public function getMinLength(): int
|
||||
{
|
||||
return $this->minLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given processor to this staggered delimiter processor
|
||||
*
|
||||
* @param DelimiterProcessorInterface $processor
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add(DelimiterProcessorInterface $processor)
|
||||
{
|
||||
$len = $processor->getMinLength();
|
||||
|
||||
if (isset($this->processors[$len])) {
|
||||
throw new \InvalidArgumentException(\sprintf('Cannot add two delimiter processors for char "%s" and minimum length %d', $this->delimiterChar, $len));
|
||||
}
|
||||
|
||||
$this->processors[$len] = $processor;
|
||||
\krsort($this->processors);
|
||||
|
||||
$this->minLength = \min($this->minLength, $len);
|
||||
}
|
||||
|
||||
public function getDelimiterUse(DelimiterInterface $opener, DelimiterInterface $closer): int
|
||||
{
|
||||
return $this->findProcessor($opener->getLength())->getDelimiterUse($opener, $closer);
|
||||
}
|
||||
|
||||
public function process(AbstractStringContainer $opener, AbstractStringContainer $closer, int $delimiterUse)
|
||||
{
|
||||
$this->findProcessor($delimiterUse)->process($opener, $closer, $delimiterUse);
|
||||
}
|
||||
|
||||
private function findProcessor(int $len): DelimiterProcessorInterface
|
||||
{
|
||||
// Find the "longest" processor which can handle this length
|
||||
foreach ($this->processors as $processor) {
|
||||
if ($processor->getMinLength() <= $len) {
|
||||
return $processor;
|
||||
}
|
||||
}
|
||||
|
||||
// Just use the first one in our list
|
||||
/** @var DelimiterProcessorInterface $first */
|
||||
$first = \reset($this->processors);
|
||||
|
||||
return $first;
|
||||
}
|
||||
}
|
||||
237
vendor/league/commonmark/src/DocParser.php
vendored
Normal file
237
vendor/league/commonmark/src/DocParser.php
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Block\Element\AbstractStringContainerBlock;
|
||||
use League\CommonMark\Block\Element\Document;
|
||||
use League\CommonMark\Block\Element\Paragraph;
|
||||
use League\CommonMark\Block\Element\StringContainerInterface;
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Event\DocumentPreParsedEvent;
|
||||
use League\CommonMark\Input\MarkdownInput;
|
||||
|
||||
final class DocParser implements DocParserInterface
|
||||
{
|
||||
/**
|
||||
* @var EnvironmentInterface
|
||||
*/
|
||||
private $environment;
|
||||
|
||||
/**
|
||||
* @var InlineParserEngine
|
||||
*/
|
||||
private $inlineParserEngine;
|
||||
|
||||
/**
|
||||
* @var int|float
|
||||
*/
|
||||
private $maxNestingLevel;
|
||||
|
||||
/**
|
||||
* @param EnvironmentInterface $environment
|
||||
*/
|
||||
public function __construct(EnvironmentInterface $environment)
|
||||
{
|
||||
$this->environment = $environment;
|
||||
$this->inlineParserEngine = new InlineParserEngine($environment);
|
||||
$this->maxNestingLevel = $environment->getConfig('max_nesting_level', \PHP_INT_MAX);
|
||||
|
||||
if (\is_float($this->maxNestingLevel)) {
|
||||
if ($this->maxNestingLevel === \INF) {
|
||||
@\trigger_error('Using the "INF" constant for the "max_nesting_level" configuration option is deprecated in league/commonmark 1.6 and will not be allowed in 2.0; use "PHP_INT_MAX" instead', \E_USER_DEPRECATED);
|
||||
} else {
|
||||
@\trigger_error('Using a float for the "max_nesting_level" configuration option is deprecated in league/commonmark 1.6 and will not be allowed in 2.0', \E_USER_DEPRECATED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $input
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*
|
||||
* @return Document
|
||||
*/
|
||||
public function parse(string $input): Document
|
||||
{
|
||||
$document = new Document();
|
||||
|
||||
$preParsedEvent = new DocumentPreParsedEvent($document, new MarkdownInput($input));
|
||||
$this->environment->dispatch($preParsedEvent);
|
||||
$markdown = $preParsedEvent->getMarkdown();
|
||||
|
||||
$context = new Context($document, $this->environment);
|
||||
|
||||
foreach ($markdown->getLines() as $line) {
|
||||
$context->setNextLine($line);
|
||||
$this->incorporateLine($context);
|
||||
}
|
||||
|
||||
$lineCount = $markdown->getLineCount();
|
||||
while ($tip = $context->getTip()) {
|
||||
$tip->finalize($context, $lineCount);
|
||||
}
|
||||
|
||||
$this->processInlines($context);
|
||||
|
||||
$this->environment->dispatch(new DocumentParsedEvent($document));
|
||||
|
||||
return $document;
|
||||
}
|
||||
|
||||
private function incorporateLine(ContextInterface $context): void
|
||||
{
|
||||
$context->getBlockCloser()->resetTip();
|
||||
$context->setBlocksParsed(false);
|
||||
|
||||
$cursor = new Cursor($context->getLine());
|
||||
|
||||
$this->resetContainer($context, $cursor);
|
||||
$context->getBlockCloser()->setLastMatchedContainer($context->getContainer());
|
||||
|
||||
$this->parseBlocks($context, $cursor);
|
||||
|
||||
// What remains at the offset is a text line. Add the text to the appropriate container.
|
||||
// First check for a lazy paragraph continuation:
|
||||
if ($this->handleLazyParagraphContinuation($context, $cursor)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// not a lazy continuation
|
||||
// finalize any blocks not matched
|
||||
$context->getBlockCloser()->closeUnmatchedBlocks();
|
||||
|
||||
// Determine whether the last line is blank, updating parents as needed
|
||||
$this->setAndPropagateLastLineBlank($context, $cursor);
|
||||
|
||||
// Handle any remaining cursor contents
|
||||
if ($context->getContainer() instanceof StringContainerInterface) {
|
||||
$context->getContainer()->handleRemainingContents($context, $cursor);
|
||||
} elseif (!$cursor->isBlank()) {
|
||||
// Create paragraph container for line
|
||||
$p = new Paragraph();
|
||||
$context->addBlock($p);
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
$p->addLine($cursor->getRemainder());
|
||||
}
|
||||
}
|
||||
|
||||
private function processInlines(ContextInterface $context): void
|
||||
{
|
||||
$walker = $context->getDocument()->walker();
|
||||
|
||||
while ($event = $walker->next()) {
|
||||
if (!$event->isEntering()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$node = $event->getNode();
|
||||
if ($node instanceof AbstractStringContainerBlock) {
|
||||
$this->inlineParserEngine->parse($node, $context->getDocument()->getReferenceMap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the container to the last open child (or its parent)
|
||||
*
|
||||
* @param ContextInterface $context
|
||||
* @param Cursor $cursor
|
||||
*/
|
||||
private function resetContainer(ContextInterface $context, Cursor $cursor): void
|
||||
{
|
||||
$container = $context->getDocument();
|
||||
|
||||
while ($lastChild = $container->lastChild()) {
|
||||
if (!($lastChild instanceof AbstractBlock)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$lastChild->isOpen()) {
|
||||
break;
|
||||
}
|
||||
|
||||
$container = $lastChild;
|
||||
if (!$container->matchesNextLine($cursor)) {
|
||||
$container = $container->parent(); // back up to the last matching block
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$context->setContainer($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse blocks
|
||||
*
|
||||
* @param ContextInterface $context
|
||||
* @param Cursor $cursor
|
||||
*/
|
||||
private function parseBlocks(ContextInterface $context, Cursor $cursor): void
|
||||
{
|
||||
while (!$context->getContainer()->isCode() && !$context->getBlocksParsed()) {
|
||||
$parsed = false;
|
||||
foreach ($this->environment->getBlockParsers() as $parser) {
|
||||
if ($parser->parse($context, $cursor)) {
|
||||
$parsed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$parsed || $context->getContainer() instanceof StringContainerInterface || (($tip = $context->getTip()) && $tip->getDepth() >= $this->maxNestingLevel)) {
|
||||
$context->setBlocksParsed(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function handleLazyParagraphContinuation(ContextInterface $context, Cursor $cursor): bool
|
||||
{
|
||||
$tip = $context->getTip();
|
||||
|
||||
if ($tip instanceof Paragraph &&
|
||||
!$context->getBlockCloser()->areAllClosed() &&
|
||||
!$cursor->isBlank() &&
|
||||
\count($tip->getStrings()) > 0) {
|
||||
|
||||
// lazy paragraph continuation
|
||||
$tip->addLine($cursor->getRemainder());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function setAndPropagateLastLineBlank(ContextInterface $context, Cursor $cursor): void
|
||||
{
|
||||
$container = $context->getContainer();
|
||||
|
||||
if ($cursor->isBlank() && $lastChild = $container->lastChild()) {
|
||||
if ($lastChild instanceof AbstractBlock) {
|
||||
$lastChild->setLastLineBlank(true);
|
||||
}
|
||||
}
|
||||
|
||||
$lastLineBlank = $container->shouldLastLineBeBlank($cursor, $context->getLineNumber());
|
||||
|
||||
// Propagate lastLineBlank up through parents:
|
||||
while ($container instanceof AbstractBlock && $container->endsWithBlankLine() !== $lastLineBlank) {
|
||||
$container->setLastLineBlank($lastLineBlank);
|
||||
$container = $container->parent();
|
||||
}
|
||||
}
|
||||
}
|
||||
26
vendor/league/commonmark/src/DocParserInterface.php
vendored
Normal file
26
vendor/league/commonmark/src/DocParserInterface.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark;
|
||||
|
||||
use League\CommonMark\Block\Element\Document;
|
||||
|
||||
interface DocParserInterface
|
||||
{
|
||||
/**
|
||||
* @param string $input
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*
|
||||
* @return Document
|
||||
*/
|
||||
public function parse(string $input): Document;
|
||||
}
|
||||
64
vendor/league/commonmark/src/ElementRendererInterface.php
vendored
Normal file
64
vendor/league/commonmark/src/ElementRendererInterface.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Inline\Element\AbstractInline;
|
||||
|
||||
/**
|
||||
* Renders a parsed AST to a string representation
|
||||
*/
|
||||
interface ElementRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param string $option
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getOption(string $option, $default = null);
|
||||
|
||||
/**
|
||||
* @param AbstractInline $inline
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function renderInline(AbstractInline $inline): string;
|
||||
|
||||
/**
|
||||
* @param AbstractInline[] $inlines
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function renderInlines(iterable $inlines): string;
|
||||
|
||||
/**
|
||||
* @param AbstractBlock $block
|
||||
* @param bool $inTightList
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function renderBlock(AbstractBlock $block, bool $inTightList = false): string;
|
||||
|
||||
/**
|
||||
* @param AbstractBlock[] $blocks
|
||||
* @param bool $inTightList
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function renderBlocks(iterable $blocks, bool $inTightList = false): string;
|
||||
}
|
||||
435
vendor/league/commonmark/src/Environment.php
vendored
Normal file
435
vendor/league/commonmark/src/Environment.php
vendored
Normal file
@@ -0,0 +1,435 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark;
|
||||
|
||||
use League\CommonMark\Block\Parser\BlockParserInterface;
|
||||
use League\CommonMark\Block\Renderer\BlockRendererInterface;
|
||||
use League\CommonMark\Delimiter\Processor\DelimiterProcessorCollection;
|
||||
use League\CommonMark\Delimiter\Processor\DelimiterProcessorInterface;
|
||||
use League\CommonMark\Event\AbstractEvent;
|
||||
use League\CommonMark\Extension\CommonMarkCoreExtension;
|
||||
use League\CommonMark\Extension\ExtensionInterface;
|
||||
use League\CommonMark\Extension\GithubFlavoredMarkdownExtension;
|
||||
use League\CommonMark\Inline\Parser\InlineParserInterface;
|
||||
use League\CommonMark\Inline\Renderer\InlineRendererInterface;
|
||||
use League\CommonMark\Util\Configuration;
|
||||
use League\CommonMark\Util\ConfigurationAwareInterface;
|
||||
use League\CommonMark\Util\PrioritizedList;
|
||||
|
||||
final class Environment implements ConfigurableEnvironmentInterface
|
||||
{
|
||||
/**
|
||||
* @var ExtensionInterface[]
|
||||
*/
|
||||
private $extensions = [];
|
||||
|
||||
/**
|
||||
* @var ExtensionInterface[]
|
||||
*/
|
||||
private $uninitializedExtensions = [];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $extensionsInitialized = false;
|
||||
|
||||
/**
|
||||
* @var PrioritizedList<BlockParserInterface>
|
||||
*/
|
||||
private $blockParsers;
|
||||
|
||||
/**
|
||||
* @var PrioritizedList<InlineParserInterface>
|
||||
*/
|
||||
private $inlineParsers;
|
||||
|
||||
/**
|
||||
* @var array<string, PrioritizedList<InlineParserInterface>>
|
||||
*/
|
||||
private $inlineParsersByCharacter = [];
|
||||
|
||||
/**
|
||||
* @var DelimiterProcessorCollection
|
||||
*/
|
||||
private $delimiterProcessors;
|
||||
|
||||
/**
|
||||
* @var array<string, PrioritizedList<BlockRendererInterface>>
|
||||
*/
|
||||
private $blockRenderersByClass = [];
|
||||
|
||||
/**
|
||||
* @var array<string, PrioritizedList<InlineRendererInterface>>
|
||||
*/
|
||||
private $inlineRenderersByClass = [];
|
||||
|
||||
/**
|
||||
* @var array<string, PrioritizedList<callable>>
|
||||
*/
|
||||
private $listeners = [];
|
||||
|
||||
/**
|
||||
* @var Configuration
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $inlineParserCharacterRegex;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $config
|
||||
*/
|
||||
public function __construct(array $config = [])
|
||||
{
|
||||
$this->config = new Configuration($config);
|
||||
|
||||
$this->blockParsers = new PrioritizedList();
|
||||
$this->inlineParsers = new PrioritizedList();
|
||||
$this->delimiterProcessors = new DelimiterProcessorCollection();
|
||||
}
|
||||
|
||||
public function mergeConfig(array $config = [])
|
||||
{
|
||||
if (\func_num_args() === 0) {
|
||||
@\trigger_error('Calling Environment::mergeConfig() without any parameters is deprecated in league/commonmark 1.6 and will not be allowed in 2.0', \E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$this->assertUninitialized('Failed to modify configuration.');
|
||||
|
||||
$this->config->merge($config);
|
||||
}
|
||||
|
||||
public function setConfig(array $config = [])
|
||||
{
|
||||
@\trigger_error('The Environment::setConfig() method is deprecated in league/commonmark 1.6 and will be removed in 2.0. Use mergeConfig() instead.', \E_USER_DEPRECATED);
|
||||
|
||||
$this->assertUninitialized('Failed to modify configuration.');
|
||||
|
||||
$this->config->replace($config);
|
||||
}
|
||||
|
||||
public function getConfig($key = null, $default = null)
|
||||
{
|
||||
return $this->config->get($key, $default);
|
||||
}
|
||||
|
||||
public function addBlockParser(BlockParserInterface $parser, int $priority = 0): ConfigurableEnvironmentInterface
|
||||
{
|
||||
$this->assertUninitialized('Failed to add block parser.');
|
||||
|
||||
$this->blockParsers->add($parser, $priority);
|
||||
$this->injectEnvironmentAndConfigurationIfNeeded($parser);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addInlineParser(InlineParserInterface $parser, int $priority = 0): ConfigurableEnvironmentInterface
|
||||
{
|
||||
$this->assertUninitialized('Failed to add inline parser.');
|
||||
|
||||
$this->inlineParsers->add($parser, $priority);
|
||||
$this->injectEnvironmentAndConfigurationIfNeeded($parser);
|
||||
|
||||
foreach ($parser->getCharacters() as $character) {
|
||||
if (!isset($this->inlineParsersByCharacter[$character])) {
|
||||
$this->inlineParsersByCharacter[$character] = new PrioritizedList();
|
||||
}
|
||||
|
||||
$this->inlineParsersByCharacter[$character]->add($parser, $priority);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addDelimiterProcessor(DelimiterProcessorInterface $processor): ConfigurableEnvironmentInterface
|
||||
{
|
||||
$this->assertUninitialized('Failed to add delimiter processor.');
|
||||
$this->delimiterProcessors->add($processor);
|
||||
$this->injectEnvironmentAndConfigurationIfNeeded($processor);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addBlockRenderer($blockClass, BlockRendererInterface $blockRenderer, int $priority = 0): ConfigurableEnvironmentInterface
|
||||
{
|
||||
$this->assertUninitialized('Failed to add block renderer.');
|
||||
|
||||
if (!isset($this->blockRenderersByClass[$blockClass])) {
|
||||
$this->blockRenderersByClass[$blockClass] = new PrioritizedList();
|
||||
}
|
||||
|
||||
$this->blockRenderersByClass[$blockClass]->add($blockRenderer, $priority);
|
||||
$this->injectEnvironmentAndConfigurationIfNeeded($blockRenderer);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addInlineRenderer(string $inlineClass, InlineRendererInterface $renderer, int $priority = 0): ConfigurableEnvironmentInterface
|
||||
{
|
||||
$this->assertUninitialized('Failed to add inline renderer.');
|
||||
|
||||
if (!isset($this->inlineRenderersByClass[$inlineClass])) {
|
||||
$this->inlineRenderersByClass[$inlineClass] = new PrioritizedList();
|
||||
}
|
||||
|
||||
$this->inlineRenderersByClass[$inlineClass]->add($renderer, $priority);
|
||||
$this->injectEnvironmentAndConfigurationIfNeeded($renderer);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBlockParsers(): iterable
|
||||
{
|
||||
if (!$this->extensionsInitialized) {
|
||||
$this->initializeExtensions();
|
||||
}
|
||||
|
||||
return $this->blockParsers->getIterator();
|
||||
}
|
||||
|
||||
public function getInlineParsersForCharacter(string $character): iterable
|
||||
{
|
||||
if (!$this->extensionsInitialized) {
|
||||
$this->initializeExtensions();
|
||||
}
|
||||
|
||||
if (!isset($this->inlineParsersByCharacter[$character])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->inlineParsersByCharacter[$character]->getIterator();
|
||||
}
|
||||
|
||||
public function getDelimiterProcessors(): DelimiterProcessorCollection
|
||||
{
|
||||
if (!$this->extensionsInitialized) {
|
||||
$this->initializeExtensions();
|
||||
}
|
||||
|
||||
return $this->delimiterProcessors;
|
||||
}
|
||||
|
||||
public function getBlockRenderersForClass(string $blockClass): iterable
|
||||
{
|
||||
if (!$this->extensionsInitialized) {
|
||||
$this->initializeExtensions();
|
||||
}
|
||||
|
||||
return $this->getRenderersByClass($this->blockRenderersByClass, $blockClass, BlockRendererInterface::class);
|
||||
}
|
||||
|
||||
public function getInlineRenderersForClass(string $inlineClass): iterable
|
||||
{
|
||||
if (!$this->extensionsInitialized) {
|
||||
$this->initializeExtensions();
|
||||
}
|
||||
|
||||
return $this->getRenderersByClass($this->inlineRenderersByClass, $inlineClass, InlineRendererInterface::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all registered extensions
|
||||
*
|
||||
* @return ExtensionInterface[]
|
||||
*/
|
||||
public function getExtensions(): iterable
|
||||
{
|
||||
return $this->extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single extension
|
||||
*
|
||||
* @param ExtensionInterface $extension
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addExtension(ExtensionInterface $extension): ConfigurableEnvironmentInterface
|
||||
{
|
||||
$this->assertUninitialized('Failed to add extension.');
|
||||
|
||||
$this->extensions[] = $extension;
|
||||
$this->uninitializedExtensions[] = $extension;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function initializeExtensions(): void
|
||||
{
|
||||
// Ask all extensions to register their components
|
||||
while (!empty($this->uninitializedExtensions)) {
|
||||
foreach ($this->uninitializedExtensions as $i => $extension) {
|
||||
$extension->register($this);
|
||||
unset($this->uninitializedExtensions[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->extensionsInitialized = true;
|
||||
|
||||
// Lastly, let's build a regex which matches non-inline characters
|
||||
// This will enable a huge performance boost with inline parsing
|
||||
$this->buildInlineParserCharacterRegex();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $object
|
||||
*/
|
||||
private function injectEnvironmentAndConfigurationIfNeeded($object): void
|
||||
{
|
||||
if ($object instanceof EnvironmentAwareInterface) {
|
||||
$object->setEnvironment($this);
|
||||
}
|
||||
|
||||
if ($object instanceof ConfigurationAwareInterface) {
|
||||
$object->setConfiguration($this->config);
|
||||
}
|
||||
}
|
||||
|
||||
public static function createCommonMarkEnvironment(): ConfigurableEnvironmentInterface
|
||||
{
|
||||
$environment = new static();
|
||||
$environment->addExtension(new CommonMarkCoreExtension());
|
||||
$environment->mergeConfig([
|
||||
'renderer' => [
|
||||
'block_separator' => "\n",
|
||||
'inner_separator' => "\n",
|
||||
'soft_break' => "\n",
|
||||
],
|
||||
'html_input' => self::HTML_INPUT_ALLOW,
|
||||
'allow_unsafe_links' => true,
|
||||
'max_nesting_level' => \PHP_INT_MAX,
|
||||
]);
|
||||
|
||||
return $environment;
|
||||
}
|
||||
|
||||
public static function createGFMEnvironment(): ConfigurableEnvironmentInterface
|
||||
{
|
||||
$environment = self::createCommonMarkEnvironment();
|
||||
$environment->addExtension(new GithubFlavoredMarkdownExtension());
|
||||
|
||||
return $environment;
|
||||
}
|
||||
|
||||
public function getInlineParserCharacterRegex(): string
|
||||
{
|
||||
return $this->inlineParserCharacterRegex;
|
||||
}
|
||||
|
||||
public function addEventListener(string $eventClass, callable $listener, int $priority = 0): ConfigurableEnvironmentInterface
|
||||
{
|
||||
$this->assertUninitialized('Failed to add event listener.');
|
||||
|
||||
if (!isset($this->listeners[$eventClass])) {
|
||||
$this->listeners[$eventClass] = new PrioritizedList();
|
||||
}
|
||||
|
||||
$this->listeners[$eventClass]->add($listener, $priority);
|
||||
|
||||
if (\is_object($listener)) {
|
||||
$this->injectEnvironmentAndConfigurationIfNeeded($listener);
|
||||
} elseif (\is_array($listener) && \is_object($listener[0])) {
|
||||
$this->injectEnvironmentAndConfigurationIfNeeded($listener[0]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function dispatch(AbstractEvent $event): void
|
||||
{
|
||||
if (!$this->extensionsInitialized) {
|
||||
$this->initializeExtensions();
|
||||
}
|
||||
|
||||
$type = \get_class($event);
|
||||
|
||||
foreach ($this->listeners[$type] ?? [] as $listener) {
|
||||
if ($event->isPropagationStopped()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$listener($event);
|
||||
}
|
||||
}
|
||||
|
||||
private function buildInlineParserCharacterRegex(): void
|
||||
{
|
||||
$chars = \array_unique(\array_merge(
|
||||
\array_keys($this->inlineParsersByCharacter),
|
||||
$this->delimiterProcessors->getDelimiterCharacters()
|
||||
));
|
||||
|
||||
if (empty($chars)) {
|
||||
// If no special inline characters exist then parse the whole line
|
||||
$this->inlineParserCharacterRegex = '/^.+$/';
|
||||
} else {
|
||||
// Match any character which inline parsers are not interested in
|
||||
$this->inlineParserCharacterRegex = '/^[^' . \preg_quote(\implode('', $chars), '/') . ']+/';
|
||||
|
||||
// Only add the u modifier (which slows down performance) if we have a multi-byte UTF-8 character in our regex
|
||||
if (\strlen($this->inlineParserCharacterRegex) > \mb_strlen($this->inlineParserCharacterRegex)) {
|
||||
$this->inlineParserCharacterRegex .= 'u';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
private function assertUninitialized(string $message): void
|
||||
{
|
||||
if ($this->extensionsInitialized) {
|
||||
throw new \RuntimeException($message . ' Extensions have already been initialized.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, PrioritizedList> $list
|
||||
* @param string $class
|
||||
* @param string $type
|
||||
*
|
||||
* @return iterable
|
||||
*
|
||||
* @phpstan-template T
|
||||
*
|
||||
* @phpstan-param array<string, PrioritizedList<T>> $list
|
||||
* @phpstan-param string $class
|
||||
* @phpstan-param class-string<T> $type
|
||||
*
|
||||
* @phpstan-return iterable<T>
|
||||
*/
|
||||
private function getRenderersByClass(array &$list, string $class, string $type): iterable
|
||||
{
|
||||
// If renderers are defined for this specific class, return them immediately
|
||||
if (isset($list[$class])) {
|
||||
return $list[$class];
|
||||
}
|
||||
|
||||
while (\class_exists($parent = $parent ?? $class) && $parent = \get_parent_class($parent)) {
|
||||
if (!isset($list[$parent])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// "Cache" this result to avoid future loops
|
||||
return $list[$class] = $list[$parent];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
22
vendor/league/commonmark/src/EnvironmentAwareInterface.php
vendored
Normal file
22
vendor/league/commonmark/src/EnvironmentAwareInterface.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark;
|
||||
|
||||
interface EnvironmentAwareInterface
|
||||
{
|
||||
/**
|
||||
* @param EnvironmentInterface $environment
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setEnvironment(EnvironmentInterface $environment);
|
||||
}
|
||||
83
vendor/league/commonmark/src/EnvironmentInterface.php
vendored
Normal file
83
vendor/league/commonmark/src/EnvironmentInterface.php
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark;
|
||||
|
||||
use League\CommonMark\Block\Parser\BlockParserInterface;
|
||||
use League\CommonMark\Block\Renderer\BlockRendererInterface;
|
||||
use League\CommonMark\Delimiter\Processor\DelimiterProcessorCollection;
|
||||
use League\CommonMark\Event\AbstractEvent;
|
||||
use League\CommonMark\Inline\Parser\InlineParserInterface;
|
||||
use League\CommonMark\Inline\Renderer\InlineRendererInterface;
|
||||
|
||||
interface EnvironmentInterface
|
||||
{
|
||||
const HTML_INPUT_STRIP = 'strip';
|
||||
const HTML_INPUT_ALLOW = 'allow';
|
||||
const HTML_INPUT_ESCAPE = 'escape';
|
||||
|
||||
/**
|
||||
* @param string|null $key
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getConfig($key = null, $default = null);
|
||||
|
||||
/**
|
||||
* @return iterable<BlockParserInterface>
|
||||
*/
|
||||
public function getBlockParsers(): iterable;
|
||||
|
||||
/**
|
||||
* @param string $character
|
||||
*
|
||||
* @return iterable<InlineParserInterface>
|
||||
*/
|
||||
public function getInlineParsersForCharacter(string $character): iterable;
|
||||
|
||||
/**
|
||||
* @return DelimiterProcessorCollection
|
||||
*/
|
||||
public function getDelimiterProcessors(): DelimiterProcessorCollection;
|
||||
|
||||
/**
|
||||
* @param string $blockClass
|
||||
*
|
||||
* @return iterable<BlockRendererInterface>
|
||||
*/
|
||||
public function getBlockRenderersForClass(string $blockClass): iterable;
|
||||
|
||||
/**
|
||||
* @param string $inlineClass
|
||||
*
|
||||
* @return iterable<InlineRendererInterface>
|
||||
*/
|
||||
public function getInlineRenderersForClass(string $inlineClass): iterable;
|
||||
|
||||
/**
|
||||
* Regex which matches any character which doesn't indicate an inline element
|
||||
*
|
||||
* This allows us to parse multiple non-special characters at once
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getInlineParserCharacterRegex(): string;
|
||||
|
||||
/**
|
||||
* Dispatches the given event to listeners
|
||||
*
|
||||
* @param AbstractEvent $event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dispatch(AbstractEvent $event): void;
|
||||
}
|
||||
50
vendor/league/commonmark/src/Event/AbstractEvent.php
vendored
Normal file
50
vendor/league/commonmark/src/Event/AbstractEvent.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the Symfony EventDispatcher "Event" contract
|
||||
* - (c) 2018-2019 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Event;
|
||||
|
||||
/**
|
||||
* Base class for classes containing event data.
|
||||
*
|
||||
* This class contains no event data. It is used by events that do not pass
|
||||
* state information to an event handler when an event is raised.
|
||||
*
|
||||
* You can call the method stopPropagation() to abort the execution of
|
||||
* further listeners in your event listener.
|
||||
*/
|
||||
abstract class AbstractEvent
|
||||
{
|
||||
/** @var bool */
|
||||
private $propagationStopped = false;
|
||||
|
||||
/**
|
||||
* Returns whether further event listeners should be triggered.
|
||||
*/
|
||||
final public function isPropagationStopped(): bool
|
||||
{
|
||||
return $this->propagationStopped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the propagation of the event to further event listeners.
|
||||
*
|
||||
* If multiple event listeners are connected to the same event, no
|
||||
* further event listener will be triggered once any trigger calls
|
||||
* stopPropagation().
|
||||
*/
|
||||
final public function stopPropagation(): void
|
||||
{
|
||||
$this->propagationStopped = true;
|
||||
}
|
||||
}
|
||||
33
vendor/league/commonmark/src/Event/DocumentParsedEvent.php
vendored
Normal file
33
vendor/league/commonmark/src/Event/DocumentParsedEvent.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Event;
|
||||
|
||||
use League\CommonMark\Block\Element\Document;
|
||||
|
||||
/**
|
||||
* Event dispatched when the document has been fully parsed
|
||||
*/
|
||||
final class DocumentParsedEvent extends AbstractEvent
|
||||
{
|
||||
/** @var Document */
|
||||
private $document;
|
||||
|
||||
public function __construct(Document $document)
|
||||
{
|
||||
$this->document = $document;
|
||||
}
|
||||
|
||||
public function getDocument(): Document
|
||||
{
|
||||
return $this->document;
|
||||
}
|
||||
}
|
||||
48
vendor/league/commonmark/src/Event/DocumentPreParsedEvent.php
vendored
Normal file
48
vendor/league/commonmark/src/Event/DocumentPreParsedEvent.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Event;
|
||||
|
||||
use League\CommonMark\Block\Element\Document;
|
||||
use League\CommonMark\Input\MarkdownInputInterface;
|
||||
|
||||
/**
|
||||
* Event dispatched when the document is about to be parsed
|
||||
*/
|
||||
final class DocumentPreParsedEvent extends AbstractEvent
|
||||
{
|
||||
/** @var Document */
|
||||
private $document;
|
||||
|
||||
/** @var MarkdownInputInterface */
|
||||
private $markdown;
|
||||
|
||||
public function __construct(Document $document, MarkdownInputInterface $markdown)
|
||||
{
|
||||
$this->document = $document;
|
||||
$this->markdown = $markdown;
|
||||
}
|
||||
|
||||
public function getDocument(): Document
|
||||
{
|
||||
return $this->document;
|
||||
}
|
||||
|
||||
public function getMarkdown(): MarkdownInputInterface
|
||||
{
|
||||
return $this->markdown;
|
||||
}
|
||||
|
||||
public function replaceMarkdown(MarkdownInputInterface $markdownInput): void
|
||||
{
|
||||
$this->markdown = $markdownInput;
|
||||
}
|
||||
}
|
||||
16
vendor/league/commonmark/src/Exception/InvalidOptionException.php
vendored
Normal file
16
vendor/league/commonmark/src/Exception/InvalidOptionException.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Exception;
|
||||
|
||||
final class InvalidOptionException extends \RuntimeException
|
||||
{
|
||||
}
|
||||
16
vendor/league/commonmark/src/Exception/UnexpectedEncodingException.php
vendored
Normal file
16
vendor/league/commonmark/src/Exception/UnexpectedEncodingException.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Exception;
|
||||
|
||||
final class UnexpectedEncodingException extends \RuntimeException
|
||||
{
|
||||
}
|
||||
32
vendor/league/commonmark/src/Extension/Attributes/AttributesExtension.php
vendored
Normal file
32
vendor/league/commonmark/src/Extension/Attributes/AttributesExtension.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) 2015 Martin Hasoň <martin.hason@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Attributes;
|
||||
|
||||
use League\CommonMark\ConfigurableEnvironmentInterface;
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\Attributes\Event\AttributesListener;
|
||||
use League\CommonMark\Extension\Attributes\Parser\AttributesBlockParser;
|
||||
use League\CommonMark\Extension\Attributes\Parser\AttributesInlineParser;
|
||||
use League\CommonMark\Extension\ExtensionInterface;
|
||||
|
||||
final class AttributesExtension implements ExtensionInterface
|
||||
{
|
||||
public function register(ConfigurableEnvironmentInterface $environment)
|
||||
{
|
||||
$environment->addBlockParser(new AttributesBlockParser());
|
||||
$environment->addInlineParser(new AttributesInlineParser());
|
||||
$environment->addEventListener(DocumentParsedEvent::class, [new AttributesListener(), 'processDocument']);
|
||||
}
|
||||
}
|
||||
141
vendor/league/commonmark/src/Extension/Attributes/Event/AttributesListener.php
vendored
Normal file
141
vendor/league/commonmark/src/Extension/Attributes/Event/AttributesListener.php
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) 2015 Martin Hasoň <martin.hason@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Attributes\Event;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Block\Element\FencedCode;
|
||||
use League\CommonMark\Block\Element\ListBlock;
|
||||
use League\CommonMark\Block\Element\ListItem;
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\Attributes\Node\Attributes;
|
||||
use League\CommonMark\Extension\Attributes\Node\AttributesInline;
|
||||
use League\CommonMark\Extension\Attributes\Util\AttributesHelper;
|
||||
use League\CommonMark\Inline\Element\AbstractInline;
|
||||
use League\CommonMark\Node\Node;
|
||||
|
||||
final class AttributesListener
|
||||
{
|
||||
private const DIRECTION_PREFIX = 'prefix';
|
||||
private const DIRECTION_SUFFIX = 'suffix';
|
||||
|
||||
public function processDocument(DocumentParsedEvent $event): void
|
||||
{
|
||||
$walker = $event->getDocument()->walker();
|
||||
while ($event = $walker->next()) {
|
||||
$node = $event->getNode();
|
||||
if (!$node instanceof AttributesInline && ($event->isEntering() || !$node instanceof Attributes)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
[$target, $direction] = self::findTargetAndDirection($node);
|
||||
|
||||
if ($target instanceof AbstractBlock || $target instanceof AbstractInline) {
|
||||
$parent = $target->parent();
|
||||
if ($parent instanceof ListItem && $parent->parent() instanceof ListBlock && $parent->parent()->isTight()) {
|
||||
$target = $parent;
|
||||
}
|
||||
|
||||
if ($direction === self::DIRECTION_SUFFIX) {
|
||||
$attributes = AttributesHelper::mergeAttributes($target, $node->getAttributes());
|
||||
} else {
|
||||
$attributes = AttributesHelper::mergeAttributes($node->getAttributes(), $target);
|
||||
}
|
||||
|
||||
$target->data['attributes'] = $attributes;
|
||||
}
|
||||
|
||||
if ($node instanceof AbstractBlock && $node->endsWithBlankLine() && $node->next() && $node->previous()) {
|
||||
$previous = $node->previous();
|
||||
if ($previous instanceof AbstractBlock) {
|
||||
$previous->setLastLineBlank(true);
|
||||
}
|
||||
}
|
||||
|
||||
$node->detach();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node $node
|
||||
*
|
||||
* @return array<Node|string|null>
|
||||
*/
|
||||
private static function findTargetAndDirection(Node $node): array
|
||||
{
|
||||
$target = null;
|
||||
$direction = null;
|
||||
$previous = $next = $node;
|
||||
while (true) {
|
||||
$previous = self::getPrevious($previous);
|
||||
$next = self::getNext($next);
|
||||
|
||||
if ($previous === null && $next === null) {
|
||||
if (!$node->parent() instanceof FencedCode) {
|
||||
$target = $node->parent();
|
||||
$direction = self::DIRECTION_SUFFIX;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ($node instanceof AttributesInline && ($previous === null || ($previous instanceof AbstractInline && $node->isBlock()))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($previous !== null && !self::isAttributesNode($previous)) {
|
||||
$target = $previous;
|
||||
$direction = self::DIRECTION_SUFFIX;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ($next !== null && !self::isAttributesNode($next)) {
|
||||
$target = $next;
|
||||
$direction = self::DIRECTION_PREFIX;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return [$target, $direction];
|
||||
}
|
||||
|
||||
private static function getPrevious(?Node $node = null): ?Node
|
||||
{
|
||||
$previous = $node instanceof Node ? $node->previous() : null;
|
||||
|
||||
if ($previous instanceof AbstractBlock && $previous->endsWithBlankLine()) {
|
||||
$previous = null;
|
||||
}
|
||||
|
||||
return $previous;
|
||||
}
|
||||
|
||||
private static function getNext(?Node $node = null): ?Node
|
||||
{
|
||||
$next = $node instanceof Node ? $node->next() : null;
|
||||
|
||||
if ($node instanceof AbstractBlock && $node->endsWithBlankLine()) {
|
||||
$next = null;
|
||||
}
|
||||
|
||||
return $next;
|
||||
}
|
||||
|
||||
private static function isAttributesNode(Node $node): bool
|
||||
{
|
||||
return $node instanceof Attributes || $node instanceof AttributesInline;
|
||||
}
|
||||
}
|
||||
62
vendor/league/commonmark/src/Extension/Attributes/Node/Attributes.php
vendored
Normal file
62
vendor/league/commonmark/src/Extension/Attributes/Node/Attributes.php
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) 2015 Martin Hasoň <martin.hason@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Attributes\Node;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Cursor;
|
||||
|
||||
final class Attributes extends AbstractBlock
|
||||
{
|
||||
/** @var array<string, mixed> */
|
||||
private $attributes;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $attributes
|
||||
*/
|
||||
public function __construct(array $attributes)
|
||||
{
|
||||
$this->attributes = $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getAttributes(): array
|
||||
{
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
public function canContain(AbstractBlock $block): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isCode(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function matchesNextLine(Cursor $cursor): bool
|
||||
{
|
||||
$this->setLastLineBlank($cursor->isBlank());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function shouldLastLineBeBlank(Cursor $cursor, int $currentLineNumber): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
50
vendor/league/commonmark/src/Extension/Attributes/Node/AttributesInline.php
vendored
Normal file
50
vendor/league/commonmark/src/Extension/Attributes/Node/AttributesInline.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) 2015 Martin Hasoň <martin.hason@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Attributes\Node;
|
||||
|
||||
use League\CommonMark\Inline\Element\AbstractInline;
|
||||
|
||||
final class AttributesInline extends AbstractInline
|
||||
{
|
||||
/** @var array<string, mixed> */
|
||||
public $attributes;
|
||||
|
||||
/** @var bool */
|
||||
public $block;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $attributes
|
||||
* @param bool $block
|
||||
*/
|
||||
public function __construct(array $attributes, bool $block)
|
||||
{
|
||||
$this->attributes = $attributes;
|
||||
$this->block = $block;
|
||||
$this->data = ['delim' => true]; // TODO: Re-implement as a delimiter?
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getAttributes(): array
|
||||
{
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
public function isBlock(): bool
|
||||
{
|
||||
return $this->block;
|
||||
}
|
||||
}
|
||||
44
vendor/league/commonmark/src/Extension/Attributes/Parser/AttributesBlockParser.php
vendored
Normal file
44
vendor/league/commonmark/src/Extension/Attributes/Parser/AttributesBlockParser.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) 2015 Martin Hasoň <martin.hason@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Attributes\Parser;
|
||||
|
||||
use League\CommonMark\Block\Parser\BlockParserInterface;
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
use League\CommonMark\Extension\Attributes\Node\Attributes;
|
||||
use League\CommonMark\Extension\Attributes\Util\AttributesHelper;
|
||||
|
||||
final class AttributesBlockParser implements BlockParserInterface
|
||||
{
|
||||
public function parse(ContextInterface $context, Cursor $cursor): bool
|
||||
{
|
||||
$state = $cursor->saveState();
|
||||
$attributes = AttributesHelper::parseAttributes($cursor);
|
||||
if ($attributes === []) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($cursor->getNextNonSpaceCharacter() !== null) {
|
||||
$cursor->restoreState($state);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$context->addBlock(new Attributes($attributes));
|
||||
$context->setBlocksParsed(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
57
vendor/league/commonmark/src/Extension/Attributes/Parser/AttributesInlineParser.php
vendored
Normal file
57
vendor/league/commonmark/src/Extension/Attributes/Parser/AttributesInlineParser.php
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) 2015 Martin Hasoň <martin.hason@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Attributes\Parser;
|
||||
|
||||
use League\CommonMark\Extension\Attributes\Node\AttributesInline;
|
||||
use League\CommonMark\Extension\Attributes\Util\AttributesHelper;
|
||||
use League\CommonMark\Inline\Element\Text;
|
||||
use League\CommonMark\Inline\Parser\InlineParserInterface;
|
||||
use League\CommonMark\InlineParserContext;
|
||||
|
||||
final class AttributesInlineParser implements InlineParserInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCharacters(): array
|
||||
{
|
||||
return ['{'];
|
||||
}
|
||||
|
||||
public function parse(InlineParserContext $inlineContext): bool
|
||||
{
|
||||
$cursor = $inlineContext->getCursor();
|
||||
|
||||
$char = (string) $cursor->peek(-1);
|
||||
|
||||
$attributes = AttributesHelper::parseAttributes($cursor);
|
||||
if ($attributes === []) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($char === ' ' && ($previousInline = $inlineContext->getContainer()->lastChild()) instanceof Text) {
|
||||
$previousInline->setContent(\rtrim($previousInline->getContent(), ' '));
|
||||
}
|
||||
|
||||
if ($char === '') {
|
||||
$cursor->advanceToNextNonSpaceOrNewline();
|
||||
}
|
||||
|
||||
$node = new AttributesInline($attributes, $char === ' ' || $char === '');
|
||||
$inlineContext->getContainer()->appendChild($node);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
130
vendor/league/commonmark/src/Extension/Attributes/Util/AttributesHelper.php
vendored
Normal file
130
vendor/league/commonmark/src/Extension/Attributes/Util/AttributesHelper.php
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) 2015 Martin Hasoň <martin.hason@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Attributes\Util;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Cursor;
|
||||
use League\CommonMark\Inline\Element\AbstractInline;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class AttributesHelper
|
||||
{
|
||||
/**
|
||||
* @param Cursor $cursor
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public static function parseAttributes(Cursor $cursor): array
|
||||
{
|
||||
$state = $cursor->saveState();
|
||||
$cursor->advanceToNextNonSpaceOrNewline();
|
||||
if ($cursor->getCharacter() !== '{') {
|
||||
$cursor->restoreState($state);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
$cursor->advanceBy(1);
|
||||
if ($cursor->getCharacter() === ':') {
|
||||
$cursor->advanceBy(1);
|
||||
}
|
||||
|
||||
$attributes = [];
|
||||
$regex = '/^\s*([.#][_a-z0-9-]+|' . RegexHelper::PARTIAL_ATTRIBUTENAME . RegexHelper::PARTIAL_ATTRIBUTEVALUESPEC . ')(?<!})\s*/i';
|
||||
while ($attribute = \trim((string) $cursor->match($regex))) {
|
||||
if ($attribute[0] === '#') {
|
||||
$attributes['id'] = \substr($attribute, 1);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($attribute[0] === '.') {
|
||||
$attributes['class'][] = \substr($attribute, 1);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
[$name, $value] = \explode('=', $attribute, 2);
|
||||
$first = $value[0];
|
||||
$last = \substr($value, -1);
|
||||
if ((($first === '"' && $last === '"') || ($first === "'" && $last === "'")) && \strlen($value) > 1) {
|
||||
$value = \substr($value, 1, -1);
|
||||
}
|
||||
|
||||
if (\strtolower(\trim($name)) === 'class') {
|
||||
foreach (\array_filter(\explode(' ', \trim($value))) as $class) {
|
||||
$attributes['class'][] = $class;
|
||||
}
|
||||
} else {
|
||||
$attributes[trim($name)] = trim($value);
|
||||
}
|
||||
}
|
||||
|
||||
if ($cursor->match('/}/') === null) {
|
||||
$cursor->restoreState($state);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($attributes === []) {
|
||||
$cursor->restoreState($state);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
if (isset($attributes['class'])) {
|
||||
$attributes['class'] = \implode(' ', (array) $attributes['class']);
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AbstractBlock|AbstractInline|array<string, mixed> $attributes1
|
||||
* @param AbstractBlock|AbstractInline|array<string, mixed> $attributes2
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public static function mergeAttributes($attributes1, $attributes2): array
|
||||
{
|
||||
$attributes = [];
|
||||
foreach ([$attributes1, $attributes2] as $arg) {
|
||||
if ($arg instanceof AbstractBlock || $arg instanceof AbstractInline) {
|
||||
$arg = $arg->data['attributes'] ?? [];
|
||||
}
|
||||
|
||||
/** @var array<string, mixed> $arg */
|
||||
$arg = (array) $arg;
|
||||
if (isset($arg['class'])) {
|
||||
foreach (\array_filter(\explode(' ', \trim($arg['class']))) as $class) {
|
||||
$attributes['class'][] = $class;
|
||||
}
|
||||
|
||||
unset($arg['class']);
|
||||
}
|
||||
|
||||
$attributes = \array_merge($attributes, $arg);
|
||||
}
|
||||
|
||||
if (isset($attributes['class'])) {
|
||||
$attributes['class'] = \implode(' ', $attributes['class']);
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
}
|
||||
25
vendor/league/commonmark/src/Extension/Autolink/AutolinkExtension.php
vendored
Normal file
25
vendor/league/commonmark/src/Extension/Autolink/AutolinkExtension.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\Autolink;
|
||||
|
||||
use League\CommonMark\ConfigurableEnvironmentInterface;
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\ExtensionInterface;
|
||||
|
||||
final class AutolinkExtension implements ExtensionInterface
|
||||
{
|
||||
public function register(ConfigurableEnvironmentInterface $environment)
|
||||
{
|
||||
$environment->addEventListener(DocumentParsedEvent::class, new EmailAutolinkProcessor());
|
||||
$environment->addEventListener(DocumentParsedEvent::class, new UrlAutolinkProcessor());
|
||||
}
|
||||
}
|
||||
78
vendor/league/commonmark/src/Extension/Autolink/EmailAutolinkProcessor.php
vendored
Normal file
78
vendor/league/commonmark/src/Extension/Autolink/EmailAutolinkProcessor.php
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\Autolink;
|
||||
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Inline\Element\Link;
|
||||
use League\CommonMark\Inline\Element\Text;
|
||||
|
||||
final class EmailAutolinkProcessor
|
||||
{
|
||||
const REGEX = '/([A-Za-z0-9.\-_+]+@[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_.]+)/';
|
||||
|
||||
/**
|
||||
* @param DocumentParsedEvent $e
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __invoke(DocumentParsedEvent $e)
|
||||
{
|
||||
$walker = $e->getDocument()->walker();
|
||||
|
||||
while ($event = $walker->next()) {
|
||||
$node = $event->getNode();
|
||||
if ($node instanceof Text && !($node->parent() instanceof Link)) {
|
||||
self::processAutolinks($node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function processAutolinks(Text $node): void
|
||||
{
|
||||
$contents = \preg_split(self::REGEX, $node->getContent(), -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
if ($contents === false || \count($contents) === 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
$leftovers = '';
|
||||
foreach ($contents as $i => $content) {
|
||||
if ($i % 2 === 0) {
|
||||
$text = $leftovers . $content;
|
||||
if ($text !== '') {
|
||||
$node->insertBefore(new Text($leftovers . $content));
|
||||
}
|
||||
|
||||
$leftovers = '';
|
||||
continue;
|
||||
}
|
||||
|
||||
// Does the URL end with punctuation that should be stripped?
|
||||
if (\substr($content, -1) === '.') {
|
||||
// Add the punctuation later
|
||||
$content = \substr($content, 0, -1);
|
||||
$leftovers = '.';
|
||||
}
|
||||
|
||||
// The last character cannot be - or _
|
||||
if (\in_array(\substr($content, -1), ['-', '_'])) {
|
||||
$node->insertBefore(new Text($content . $leftovers));
|
||||
$leftovers = '';
|
||||
continue;
|
||||
}
|
||||
|
||||
$node->insertBefore(new Link('mailto:' . $content, $content));
|
||||
}
|
||||
|
||||
$node->detach();
|
||||
}
|
||||
}
|
||||
96
vendor/league/commonmark/src/Extension/Autolink/InlineMentionParser.php
vendored
Normal file
96
vendor/league/commonmark/src/Extension/Autolink/InlineMentionParser.php
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\Autolink;
|
||||
|
||||
use League\CommonMark\Extension\Mention\MentionParser;
|
||||
use League\CommonMark\Inline\Element\Link;
|
||||
use League\CommonMark\Inline\Parser\InlineParserInterface;
|
||||
use League\CommonMark\InlineParserContext;
|
||||
|
||||
@trigger_error(sprintf('%s is deprecated; use %s instead', InlineMentionParser::class, MentionParser::class), E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* @deprecated Use MentionParser instead
|
||||
*/
|
||||
final class InlineMentionParser implements InlineParserInterface
|
||||
{
|
||||
/** @var string */
|
||||
private $linkPattern;
|
||||
|
||||
/** @var string */
|
||||
private $handleRegex;
|
||||
|
||||
/**
|
||||
* @param string $linkPattern
|
||||
* @param string $handleRegex
|
||||
*/
|
||||
public function __construct($linkPattern, $handleRegex = '/^[A-Za-z0-9_]+(?!\w)/')
|
||||
{
|
||||
$this->linkPattern = $linkPattern;
|
||||
$this->handleRegex = $handleRegex;
|
||||
}
|
||||
|
||||
public function getCharacters(): array
|
||||
{
|
||||
return ['@'];
|
||||
}
|
||||
|
||||
public function parse(InlineParserContext $inlineContext): bool
|
||||
{
|
||||
$cursor = $inlineContext->getCursor();
|
||||
|
||||
// The @ symbol must not have any other characters immediately prior
|
||||
$previousChar = $cursor->peek(-1);
|
||||
if ($previousChar !== null && $previousChar !== ' ') {
|
||||
// peek() doesn't modify the cursor, so no need to restore state first
|
||||
return false;
|
||||
}
|
||||
|
||||
// Save the cursor state in case we need to rewind and bail
|
||||
$previousState = $cursor->saveState();
|
||||
|
||||
// Advance past the @ symbol to keep parsing simpler
|
||||
$cursor->advance();
|
||||
|
||||
// Parse the handle
|
||||
$handle = $cursor->match($this->handleRegex);
|
||||
if (empty($handle)) {
|
||||
// Regex failed to match; this isn't a valid Twitter handle
|
||||
$cursor->restoreState($previousState);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$url = \sprintf($this->linkPattern, $handle);
|
||||
|
||||
$inlineContext->getContainer()->appendChild(new Link($url, '@' . $handle));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return InlineMentionParser
|
||||
*/
|
||||
public static function createTwitterHandleParser()
|
||||
{
|
||||
return new self('https://twitter.com/%s', '/^[A-Za-z0-9_]{1,15}(?!\w)/');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return InlineMentionParser
|
||||
*/
|
||||
public static function createGithubHandleParser()
|
||||
{
|
||||
// RegEx adapted from https://github.com/shinnn/github-username-regex/blob/master/index.js
|
||||
return new self('https://www.github.com/%s', '/^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}(?!\w)/');
|
||||
}
|
||||
}
|
||||
153
vendor/league/commonmark/src/Extension/Autolink/UrlAutolinkProcessor.php
vendored
Normal file
153
vendor/league/commonmark/src/Extension/Autolink/UrlAutolinkProcessor.php
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\Autolink;
|
||||
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Inline\Element\Link;
|
||||
use League\CommonMark\Inline\Element\Text;
|
||||
|
||||
final class UrlAutolinkProcessor
|
||||
{
|
||||
// RegEx adapted from https://github.com/symfony/symfony/blob/4.2/src/Symfony/Component/Validator/Constraints/UrlValidator.php
|
||||
const REGEX = '~
|
||||
(?<=^|[ \\t\\n\\x0b\\x0c\\x0d*_\\~\\(]) # Can only come at the beginning of a line, after whitespace, or certain delimiting characters
|
||||
(
|
||||
# Must start with a supported scheme + auth, or "www"
|
||||
(?:
|
||||
(?:%s):// # protocol
|
||||
(?:([\.\pL\pN-]+:)?([\.\pL\pN-]+)@)? # basic auth
|
||||
|www\.)
|
||||
(?:
|
||||
(?:[\pL\pN\pS\-\.])+(?:\.?(?:[\pL\pN]|xn\-\-[\pL\pN-]+)+\.?) # a domain name
|
||||
| # or
|
||||
\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} # an IP address
|
||||
| # or
|
||||
\[
|
||||
(?:(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-f]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,1}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,2}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,3}(?:(?:[0-9a-f]{1,4})))?::(?:(?:[0-9a-f]{1,4})):)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,4}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,5}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,6}(?:(?:[0-9a-f]{1,4})))?::))))
|
||||
\] # an IPv6 address
|
||||
)
|
||||
(?::[0-9]+)? # a port (optional)
|
||||
(?:/ (?:[\pL\pN\-._\~!$&\'()*+,;=:@]|%%[0-9A-Fa-f]{2})* )* # a path
|
||||
(?:\? (?:[\pL\pN\-._\~!$&\'()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a query (optional)
|
||||
(?:\# (?:[\pL\pN\-._\~!$&\'()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a fragment (optional)
|
||||
)~ixu';
|
||||
|
||||
/** @var string */
|
||||
private $finalRegex;
|
||||
|
||||
/**
|
||||
* @param array<int, string> $allowedProtocols
|
||||
*/
|
||||
public function __construct(array $allowedProtocols = ['http', 'https', 'ftp'])
|
||||
{
|
||||
$this->finalRegex = \sprintf(self::REGEX, \implode('|', $allowedProtocols));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DocumentParsedEvent $e
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __invoke(DocumentParsedEvent $e)
|
||||
{
|
||||
$walker = $e->getDocument()->walker();
|
||||
|
||||
while ($event = $walker->next()) {
|
||||
$node = $event->getNode();
|
||||
if ($node instanceof Text && !($node->parent() instanceof Link)) {
|
||||
self::processAutolinks($node, $this->finalRegex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function processAutolinks(Text $node, string $regex): void
|
||||
{
|
||||
$contents = \preg_split($regex, $node->getContent(), -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
if ($contents === false || \count($contents) === 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
$leftovers = '';
|
||||
foreach ($contents as $i => $content) {
|
||||
// Even-indexed elements are things before/after the URLs
|
||||
if ($i % 2 === 0) {
|
||||
// Insert any left-over characters here as well
|
||||
$text = $leftovers . $content;
|
||||
if ($text !== '') {
|
||||
$node->insertBefore(new Text($leftovers . $content));
|
||||
}
|
||||
|
||||
$leftovers = '';
|
||||
continue;
|
||||
}
|
||||
|
||||
$leftovers = '';
|
||||
|
||||
// Does the URL end with punctuation that should be stripped?
|
||||
if (\preg_match('/(.+)([?!.,:*_~]+)$/', $content, $matches)) {
|
||||
// Add the punctuation later
|
||||
$content = $matches[1];
|
||||
$leftovers = $matches[2];
|
||||
}
|
||||
|
||||
// Does the URL end with something that looks like an entity reference?
|
||||
if (\preg_match('/(.+)(&[A-Za-z0-9]+;)$/', $content, $matches)) {
|
||||
$content = $matches[1];
|
||||
$leftovers = $matches[2] . $leftovers;
|
||||
}
|
||||
|
||||
// Does the URL need its closing paren chopped off?
|
||||
if (\substr($content, -1) === ')' && ($diff = self::diffParens($content)) > 0) {
|
||||
$content = \substr($content, 0, -$diff);
|
||||
$leftovers = str_repeat(')', $diff) . $leftovers;
|
||||
}
|
||||
|
||||
self::addLink($node, $content);
|
||||
}
|
||||
|
||||
$node->detach();
|
||||
}
|
||||
|
||||
private static function addLink(Text $node, string $url): void
|
||||
{
|
||||
// Auto-prefix 'http://' onto 'www' URLs
|
||||
if (\substr($url, 0, 4) === 'www.') {
|
||||
$node->insertBefore(new Link('http://' . $url, $url));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$node->insertBefore(new Link($url, $url));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private static function diffParens(string $content): int
|
||||
{
|
||||
// Scan the entire autolink for the total number of parentheses.
|
||||
// If there is a greater number of closing parentheses than opening ones,
|
||||
// we don’t consider ANY of the last characters as part of the autolink,
|
||||
// in order to facilitate including an autolink inside a parenthesis.
|
||||
\preg_match_all('/[()]/', $content, $matches);
|
||||
|
||||
$charCount = ['(' => 0, ')' => 0];
|
||||
foreach ($matches[0] as $char) {
|
||||
$charCount[$char]++;
|
||||
}
|
||||
|
||||
return $charCount[')'] - $charCount['('];
|
||||
}
|
||||
}
|
||||
95
vendor/league/commonmark/src/Extension/CommonMarkCoreExtension.php
vendored
Normal file
95
vendor/league/commonmark/src/Extension/CommonMarkCoreExtension.php
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension;
|
||||
|
||||
use League\CommonMark\Block\Element as BlockElement;
|
||||
use League\CommonMark\Block\Parser as BlockParser;
|
||||
use League\CommonMark\Block\Renderer as BlockRenderer;
|
||||
use League\CommonMark\ConfigurableEnvironmentInterface;
|
||||
use League\CommonMark\Delimiter\Processor\EmphasisDelimiterProcessor;
|
||||
use League\CommonMark\Inline\Element as InlineElement;
|
||||
use League\CommonMark\Inline\Parser as InlineParser;
|
||||
use League\CommonMark\Inline\Renderer as InlineRenderer;
|
||||
use League\CommonMark\Util\ConfigurationInterface;
|
||||
|
||||
final class CommonMarkCoreExtension implements ExtensionInterface
|
||||
{
|
||||
public function register(ConfigurableEnvironmentInterface $environment)
|
||||
{
|
||||
$environment
|
||||
->addBlockParser(new BlockParser\BlockQuoteParser(), 70)
|
||||
->addBlockParser(new BlockParser\ATXHeadingParser(), 60)
|
||||
->addBlockParser(new BlockParser\FencedCodeParser(), 50)
|
||||
->addBlockParser(new BlockParser\HtmlBlockParser(), 40)
|
||||
->addBlockParser(new BlockParser\SetExtHeadingParser(), 30)
|
||||
->addBlockParser(new BlockParser\ThematicBreakParser(), 20)
|
||||
->addBlockParser(new BlockParser\ListParser(), 10)
|
||||
->addBlockParser(new BlockParser\IndentedCodeParser(), -100)
|
||||
->addBlockParser(new BlockParser\LazyParagraphParser(), -200)
|
||||
|
||||
->addInlineParser(new InlineParser\NewlineParser(), 200)
|
||||
->addInlineParser(new InlineParser\BacktickParser(), 150)
|
||||
->addInlineParser(new InlineParser\EscapableParser(), 80)
|
||||
->addInlineParser(new InlineParser\EntityParser(), 70)
|
||||
->addInlineParser(new InlineParser\AutolinkParser(), 50)
|
||||
->addInlineParser(new InlineParser\HtmlInlineParser(), 40)
|
||||
->addInlineParser(new InlineParser\CloseBracketParser(), 30)
|
||||
->addInlineParser(new InlineParser\OpenBracketParser(), 20)
|
||||
->addInlineParser(new InlineParser\BangParser(), 10)
|
||||
|
||||
->addBlockRenderer(BlockElement\BlockQuote::class, new BlockRenderer\BlockQuoteRenderer(), 0)
|
||||
->addBlockRenderer(BlockElement\Document::class, new BlockRenderer\DocumentRenderer(), 0)
|
||||
->addBlockRenderer(BlockElement\FencedCode::class, new BlockRenderer\FencedCodeRenderer(), 0)
|
||||
->addBlockRenderer(BlockElement\Heading::class, new BlockRenderer\HeadingRenderer(), 0)
|
||||
->addBlockRenderer(BlockElement\HtmlBlock::class, new BlockRenderer\HtmlBlockRenderer(), 0)
|
||||
->addBlockRenderer(BlockElement\IndentedCode::class, new BlockRenderer\IndentedCodeRenderer(), 0)
|
||||
->addBlockRenderer(BlockElement\ListBlock::class, new BlockRenderer\ListBlockRenderer(), 0)
|
||||
->addBlockRenderer(BlockElement\ListItem::class, new BlockRenderer\ListItemRenderer(), 0)
|
||||
->addBlockRenderer(BlockElement\Paragraph::class, new BlockRenderer\ParagraphRenderer(), 0)
|
||||
->addBlockRenderer(BlockElement\ThematicBreak::class, new BlockRenderer\ThematicBreakRenderer(), 0)
|
||||
|
||||
->addInlineRenderer(InlineElement\Code::class, new InlineRenderer\CodeRenderer(), 0)
|
||||
->addInlineRenderer(InlineElement\Emphasis::class, new InlineRenderer\EmphasisRenderer(), 0)
|
||||
->addInlineRenderer(InlineElement\HtmlInline::class, new InlineRenderer\HtmlInlineRenderer(), 0)
|
||||
->addInlineRenderer(InlineElement\Image::class, new InlineRenderer\ImageRenderer(), 0)
|
||||
->addInlineRenderer(InlineElement\Link::class, new InlineRenderer\LinkRenderer(), 0)
|
||||
->addInlineRenderer(InlineElement\Newline::class, new InlineRenderer\NewlineRenderer(), 0)
|
||||
->addInlineRenderer(InlineElement\Strong::class, new InlineRenderer\StrongRenderer(), 0)
|
||||
->addInlineRenderer(InlineElement\Text::class, new InlineRenderer\TextRenderer(), 0)
|
||||
;
|
||||
|
||||
$deprecatedUseAsterisk = $environment->getConfig('use_asterisk', ConfigurationInterface::MISSING);
|
||||
if ($deprecatedUseAsterisk !== ConfigurationInterface::MISSING) {
|
||||
@\trigger_error('The "use_asterisk" configuration option is deprecated in league/commonmark 1.6 and will be replaced with "commonmark > use_asterisk" in 2.0', \E_USER_DEPRECATED);
|
||||
} else {
|
||||
$deprecatedUseAsterisk = true;
|
||||
}
|
||||
|
||||
if ($environment->getConfig('commonmark/use_asterisk', $deprecatedUseAsterisk)) {
|
||||
$environment->addDelimiterProcessor(new EmphasisDelimiterProcessor('*'));
|
||||
}
|
||||
|
||||
$deprecatedUseUnderscore = $environment->getConfig('use_underscore', ConfigurationInterface::MISSING);
|
||||
if ($deprecatedUseUnderscore !== ConfigurationInterface::MISSING) {
|
||||
@\trigger_error('The "use_underscore" configuration option is deprecated in league/commonmark 1.6 and will be replaced with "commonmark > use_underscore" in 2.0', \E_USER_DEPRECATED);
|
||||
} else {
|
||||
$deprecatedUseUnderscore = true;
|
||||
}
|
||||
|
||||
if ($environment->getConfig('commonmark/use_underscore', $deprecatedUseUnderscore)) {
|
||||
$environment->addDelimiterProcessor(new EmphasisDelimiterProcessor('_'));
|
||||
}
|
||||
}
|
||||
}
|
||||
48
vendor/league/commonmark/src/Extension/DisallowedRawHtml/DisallowedRawHtmlBlockRenderer.php
vendored
Normal file
48
vendor/league/commonmark/src/Extension/DisallowedRawHtml/DisallowedRawHtmlBlockRenderer.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\DisallowedRawHtml;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Block\Renderer\BlockRendererInterface;
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\Util\ConfigurationAwareInterface;
|
||||
use League\CommonMark\Util\ConfigurationInterface;
|
||||
|
||||
final class DisallowedRawHtmlBlockRenderer implements BlockRendererInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @var BlockRendererInterface */
|
||||
private $htmlBlockRenderer;
|
||||
|
||||
public function __construct(BlockRendererInterface $htmlBlockRenderer)
|
||||
{
|
||||
$this->htmlBlockRenderer = $htmlBlockRenderer;
|
||||
}
|
||||
|
||||
public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, bool $inTightList = false)
|
||||
{
|
||||
$rendered = $this->htmlBlockRenderer->render($block, $htmlRenderer, $inTightList);
|
||||
|
||||
if ($rendered === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Match these types of tags: <title> </title> <title x="sdf"> <title/> <title />
|
||||
return preg_replace('/<(\/?(?:title|textarea|style|xmp|iframe|noembed|noframes|script|plaintext)[ \/>])/i', '<$1', $rendered);
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration)
|
||||
{
|
||||
if ($this->htmlBlockRenderer instanceof ConfigurationAwareInterface) {
|
||||
$this->htmlBlockRenderer->setConfiguration($configuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
28
vendor/league/commonmark/src/Extension/DisallowedRawHtml/DisallowedRawHtmlExtension.php
vendored
Normal file
28
vendor/league/commonmark/src/Extension/DisallowedRawHtml/DisallowedRawHtmlExtension.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\DisallowedRawHtml;
|
||||
|
||||
use League\CommonMark\Block\Element\HtmlBlock;
|
||||
use League\CommonMark\Block\Renderer\HtmlBlockRenderer;
|
||||
use League\CommonMark\ConfigurableEnvironmentInterface;
|
||||
use League\CommonMark\Extension\ExtensionInterface;
|
||||
use League\CommonMark\Inline\Element\HtmlInline;
|
||||
use League\CommonMark\Inline\Renderer\HtmlInlineRenderer;
|
||||
|
||||
final class DisallowedRawHtmlExtension implements ExtensionInterface
|
||||
{
|
||||
public function register(ConfigurableEnvironmentInterface $environment)
|
||||
{
|
||||
$environment->addBlockRenderer(HtmlBlock::class, new DisallowedRawHtmlBlockRenderer(new HtmlBlockRenderer()), 50);
|
||||
$environment->addInlineRenderer(HtmlInline::class, new DisallowedRawHtmlInlineRenderer(new HtmlInlineRenderer()), 50);
|
||||
}
|
||||
}
|
||||
48
vendor/league/commonmark/src/Extension/DisallowedRawHtml/DisallowedRawHtmlInlineRenderer.php
vendored
Normal file
48
vendor/league/commonmark/src/Extension/DisallowedRawHtml/DisallowedRawHtmlInlineRenderer.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\DisallowedRawHtml;
|
||||
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\Inline\Element\AbstractInline;
|
||||
use League\CommonMark\Inline\Renderer\InlineRendererInterface;
|
||||
use League\CommonMark\Util\ConfigurationAwareInterface;
|
||||
use League\CommonMark\Util\ConfigurationInterface;
|
||||
|
||||
final class DisallowedRawHtmlInlineRenderer implements InlineRendererInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @var InlineRendererInterface */
|
||||
private $htmlInlineRenderer;
|
||||
|
||||
public function __construct(InlineRendererInterface $htmlBlockRenderer)
|
||||
{
|
||||
$this->htmlInlineRenderer = $htmlBlockRenderer;
|
||||
}
|
||||
|
||||
public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer)
|
||||
{
|
||||
$rendered = $this->htmlInlineRenderer->render($inline, $htmlRenderer);
|
||||
|
||||
if ($rendered === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Match these types of tags: <title> </title> <title x="sdf"> <title/> <title />
|
||||
return preg_replace('/<(\/?(?:title|textarea|style|xmp|iframe|noembed|noframes|script|plaintext)[ \/>])/i', '<$1', $rendered);
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration)
|
||||
{
|
||||
if ($this->htmlInlineRenderer instanceof ConfigurationAwareInterface) {
|
||||
$this->htmlInlineRenderer->setConfiguration($configuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
27
vendor/league/commonmark/src/Extension/ExtensionInterface.php
vendored
Normal file
27
vendor/league/commonmark/src/Extension/ExtensionInterface.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension;
|
||||
|
||||
use League\CommonMark\ConfigurableEnvironmentInterface;
|
||||
|
||||
interface ExtensionInterface
|
||||
{
|
||||
/**
|
||||
* @param ConfigurableEnvironmentInterface $environment
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register(ConfigurableEnvironmentInterface $environment);
|
||||
}
|
||||
24
vendor/league/commonmark/src/Extension/ExternalLink/ExternalLinkExtension.php
vendored
Normal file
24
vendor/league/commonmark/src/Extension/ExternalLink/ExternalLinkExtension.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\ExternalLink;
|
||||
|
||||
use League\CommonMark\ConfigurableEnvironmentInterface;
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\ExtensionInterface;
|
||||
|
||||
final class ExternalLinkExtension implements ExtensionInterface
|
||||
{
|
||||
public function register(ConfigurableEnvironmentInterface $environment)
|
||||
{
|
||||
$environment->addEventListener(DocumentParsedEvent::class, new ExternalLinkProcessor($environment), -50);
|
||||
}
|
||||
}
|
||||
131
vendor/league/commonmark/src/Extension/ExternalLink/ExternalLinkProcessor.php
vendored
Normal file
131
vendor/league/commonmark/src/Extension/ExternalLink/ExternalLinkProcessor.php
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\ExternalLink;
|
||||
|
||||
use League\CommonMark\EnvironmentInterface;
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Inline\Element\Link;
|
||||
|
||||
final class ExternalLinkProcessor
|
||||
{
|
||||
public const APPLY_NONE = '';
|
||||
public const APPLY_ALL = 'all';
|
||||
public const APPLY_EXTERNAL = 'external';
|
||||
public const APPLY_INTERNAL = 'internal';
|
||||
|
||||
/** @var EnvironmentInterface */
|
||||
private $environment;
|
||||
|
||||
public function __construct(EnvironmentInterface $environment)
|
||||
{
|
||||
$this->environment = $environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DocumentParsedEvent $e
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __invoke(DocumentParsedEvent $e)
|
||||
{
|
||||
$internalHosts = $this->environment->getConfig('external_link/internal_hosts', []);
|
||||
$openInNewWindow = $this->environment->getConfig('external_link/open_in_new_window', false);
|
||||
$classes = $this->environment->getConfig('external_link/html_class', '');
|
||||
|
||||
$walker = $e->getDocument()->walker();
|
||||
while ($event = $walker->next()) {
|
||||
if ($event->isEntering() && $event->getNode() instanceof Link) {
|
||||
/** @var Link $link */
|
||||
$link = $event->getNode();
|
||||
|
||||
$host = parse_url($link->getUrl(), PHP_URL_HOST);
|
||||
if (empty($host)) {
|
||||
// Something is terribly wrong with this URL
|
||||
continue;
|
||||
}
|
||||
|
||||
if (self::hostMatches($host, $internalHosts)) {
|
||||
$link->data['external'] = false;
|
||||
$this->applyRelAttribute($link, false);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Host does not match our list
|
||||
$this->markLinkAsExternal($link, $openInNewWindow, $classes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function markLinkAsExternal(Link $link, bool $openInNewWindow, string $classes): void
|
||||
{
|
||||
$link->data['external'] = true;
|
||||
$link->data['attributes'] = $link->getData('attributes', []);
|
||||
$this->applyRelAttribute($link, true);
|
||||
|
||||
if ($openInNewWindow) {
|
||||
$link->data['attributes']['target'] = '_blank';
|
||||
}
|
||||
|
||||
if (!empty($classes)) {
|
||||
$link->data['attributes']['class'] = trim(($link->data['attributes']['class'] ?? '') . ' ' . $classes);
|
||||
}
|
||||
}
|
||||
|
||||
private function applyRelAttribute(Link $link, bool $isExternal): void
|
||||
{
|
||||
$rel = [];
|
||||
|
||||
$options = [
|
||||
'nofollow' => $this->environment->getConfig('external_link/nofollow', self::APPLY_NONE),
|
||||
'noopener' => $this->environment->getConfig('external_link/noopener', self::APPLY_EXTERNAL),
|
||||
'noreferrer' => $this->environment->getConfig('external_link/noreferrer', self::APPLY_EXTERNAL),
|
||||
];
|
||||
|
||||
foreach ($options as $type => $option) {
|
||||
switch (true) {
|
||||
case $option === self::APPLY_ALL:
|
||||
case $isExternal && $option === self::APPLY_EXTERNAL:
|
||||
case !$isExternal && $option === self::APPLY_INTERNAL:
|
||||
$rel[] = $type;
|
||||
}
|
||||
}
|
||||
|
||||
if ($rel === []) {
|
||||
return;
|
||||
}
|
||||
|
||||
$link->data['attributes']['rel'] = \implode(' ', $rel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $host
|
||||
* @param mixed $compareTo
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @internal This method is only public so we can easily test it. DO NOT USE THIS OUTSIDE OF THIS EXTENSION!
|
||||
*/
|
||||
public static function hostMatches(string $host, $compareTo)
|
||||
{
|
||||
foreach ((array) $compareTo as $c) {
|
||||
if (strpos($c, '/') === 0) {
|
||||
if (preg_match($c, $host)) {
|
||||
return true;
|
||||
}
|
||||
} elseif ($c === $host) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
61
vendor/league/commonmark/src/Extension/Footnote/Event/AnonymousFootnotesListener.php
vendored
Normal file
61
vendor/league/commonmark/src/Extension/Footnote/Event/AnonymousFootnotesListener.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) Rezo Zero / Ambroise Maupate
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Footnote\Event;
|
||||
|
||||
use League\CommonMark\Block\Element\Paragraph;
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\Footnote\Node\Footnote;
|
||||
use League\CommonMark\Extension\Footnote\Node\FootnoteBackref;
|
||||
use League\CommonMark\Extension\Footnote\Node\FootnoteRef;
|
||||
use League\CommonMark\Inline\Element\Text;
|
||||
use League\CommonMark\Reference\Reference;
|
||||
use League\CommonMark\Util\ConfigurationAwareInterface;
|
||||
use League\CommonMark\Util\ConfigurationInterface;
|
||||
|
||||
final class AnonymousFootnotesListener implements ConfigurationAwareInterface
|
||||
{
|
||||
/** @var ConfigurationInterface */
|
||||
private $config;
|
||||
|
||||
public function onDocumentParsed(DocumentParsedEvent $event): void
|
||||
{
|
||||
$document = $event->getDocument();
|
||||
$walker = $document->walker();
|
||||
|
||||
while ($event = $walker->next()) {
|
||||
$node = $event->getNode();
|
||||
if ($node instanceof FootnoteRef && $event->isEntering() && null !== $text = $node->getContent()) {
|
||||
// Anonymous footnote needs to create a footnote from its content
|
||||
$existingReference = $node->getReference();
|
||||
$reference = new Reference(
|
||||
$existingReference->getLabel(),
|
||||
'#' . $this->config->get('footnote/ref_id_prefix', 'fnref:') . $existingReference->getLabel(),
|
||||
$existingReference->getTitle()
|
||||
);
|
||||
$footnote = new Footnote($reference);
|
||||
$footnote->addBackref(new FootnoteBackref($reference));
|
||||
$paragraph = new Paragraph();
|
||||
$paragraph->appendChild(new Text($text));
|
||||
$footnote->appendChild($paragraph);
|
||||
$document->appendChild($footnote);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $config): void
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
}
|
||||
100
vendor/league/commonmark/src/Extension/Footnote/Event/GatherFootnotesListener.php
vendored
Normal file
100
vendor/league/commonmark/src/Extension/Footnote/Event/GatherFootnotesListener.php
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) Rezo Zero / Ambroise Maupate
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Footnote\Event;
|
||||
|
||||
use League\CommonMark\Block\Element\Document;
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\Footnote\Node\Footnote;
|
||||
use League\CommonMark\Extension\Footnote\Node\FootnoteBackref;
|
||||
use League\CommonMark\Extension\Footnote\Node\FootnoteContainer;
|
||||
use League\CommonMark\Reference\Reference;
|
||||
use League\CommonMark\Util\ConfigurationAwareInterface;
|
||||
use League\CommonMark\Util\ConfigurationInterface;
|
||||
|
||||
final class GatherFootnotesListener implements ConfigurationAwareInterface
|
||||
{
|
||||
/** @var ConfigurationInterface */
|
||||
private $config;
|
||||
|
||||
public function onDocumentParsed(DocumentParsedEvent $event): void
|
||||
{
|
||||
$document = $event->getDocument();
|
||||
$walker = $document->walker();
|
||||
|
||||
$footnotes = [];
|
||||
while ($event = $walker->next()) {
|
||||
if (!$event->isEntering()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$node = $event->getNode();
|
||||
if (!$node instanceof Footnote) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Look for existing reference with footnote label
|
||||
$ref = $document->getReferenceMap()->getReference($node->getReference()->getLabel());
|
||||
if ($ref !== null) {
|
||||
// Use numeric title to get footnotes order
|
||||
$footnotes[\intval($ref->getTitle())] = $node;
|
||||
} else {
|
||||
// Footnote call is missing, append footnote at the end
|
||||
$footnotes[INF] = $node;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for all footnote refs pointing to this footnote
|
||||
* and create each footnote backrefs.
|
||||
*/
|
||||
$backrefs = $document->getData(
|
||||
'#' . $this->config->get('footnote/footnote_id_prefix', 'fn:') . $node->getReference()->getDestination(),
|
||||
[]
|
||||
);
|
||||
/** @var Reference $backref */
|
||||
foreach ($backrefs as $backref) {
|
||||
$node->addBackref(new FootnoteBackref(new Reference(
|
||||
$backref->getLabel(),
|
||||
'#' . $this->config->get('footnote/ref_id_prefix', 'fnref:') . $backref->getLabel(),
|
||||
$backref->getTitle()
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
// Only add a footnote container if there are any
|
||||
if (\count($footnotes) === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$container = $this->getFootnotesContainer($document);
|
||||
|
||||
\ksort($footnotes);
|
||||
foreach ($footnotes as $footnote) {
|
||||
$container->appendChild($footnote);
|
||||
}
|
||||
}
|
||||
|
||||
private function getFootnotesContainer(Document $document): FootnoteContainer
|
||||
{
|
||||
$footnoteContainer = new FootnoteContainer();
|
||||
$document->appendChild($footnoteContainer);
|
||||
|
||||
return $footnoteContainer;
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $config): void
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
}
|
||||
86
vendor/league/commonmark/src/Extension/Footnote/Event/NumberFootnotesListener.php
vendored
Normal file
86
vendor/league/commonmark/src/Extension/Footnote/Event/NumberFootnotesListener.php
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) Rezo Zero / Ambroise Maupate
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Footnote\Event;
|
||||
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\Footnote\Node\FootnoteRef;
|
||||
use League\CommonMark\Reference\Reference;
|
||||
|
||||
final class NumberFootnotesListener
|
||||
{
|
||||
public function onDocumentParsed(DocumentParsedEvent $event): void
|
||||
{
|
||||
$document = $event->getDocument();
|
||||
$walker = $document->walker();
|
||||
$nextCounter = 1;
|
||||
$usedLabels = [];
|
||||
$usedCounters = [];
|
||||
|
||||
while ($event = $walker->next()) {
|
||||
if (!$event->isEntering()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$node = $event->getNode();
|
||||
|
||||
if (!$node instanceof FootnoteRef) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$existingReference = $node->getReference();
|
||||
$label = $existingReference->getLabel();
|
||||
$counter = $nextCounter;
|
||||
$canIncrementCounter = true;
|
||||
|
||||
if (\array_key_exists($label, $usedLabels)) {
|
||||
/*
|
||||
* Reference is used again, we need to point
|
||||
* to the same footnote. But with a different ID
|
||||
*/
|
||||
$counter = $usedCounters[$label];
|
||||
$label = $label . '__' . ++$usedLabels[$label];
|
||||
$canIncrementCounter = false;
|
||||
}
|
||||
|
||||
// rewrite reference title to use a numeric link
|
||||
$newReference = new Reference(
|
||||
$label,
|
||||
$existingReference->getDestination(),
|
||||
(string) $counter
|
||||
);
|
||||
|
||||
// Override reference with numeric link
|
||||
$node->setReference($newReference);
|
||||
$document->getReferenceMap()->addReference($newReference);
|
||||
|
||||
/*
|
||||
* Store created references in document for
|
||||
* creating FootnoteBackrefs
|
||||
*/
|
||||
if (false === $document->getData($existingReference->getDestination(), false)) {
|
||||
$document->data[$existingReference->getDestination()] = [];
|
||||
}
|
||||
|
||||
$document->data[$existingReference->getDestination()][] = $newReference;
|
||||
|
||||
$usedLabels[$label] = 1;
|
||||
$usedCounters[$label] = $nextCounter;
|
||||
|
||||
if ($canIncrementCounter) {
|
||||
$nextCounter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
53
vendor/league/commonmark/src/Extension/Footnote/FootnoteExtension.php
vendored
Normal file
53
vendor/league/commonmark/src/Extension/Footnote/FootnoteExtension.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) Rezo Zero / Ambroise Maupate
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Footnote;
|
||||
|
||||
use League\CommonMark\ConfigurableEnvironmentInterface;
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\ExtensionInterface;
|
||||
use League\CommonMark\Extension\Footnote\Event\AnonymousFootnotesListener;
|
||||
use League\CommonMark\Extension\Footnote\Event\GatherFootnotesListener;
|
||||
use League\CommonMark\Extension\Footnote\Event\NumberFootnotesListener;
|
||||
use League\CommonMark\Extension\Footnote\Node\Footnote;
|
||||
use League\CommonMark\Extension\Footnote\Node\FootnoteBackref;
|
||||
use League\CommonMark\Extension\Footnote\Node\FootnoteContainer;
|
||||
use League\CommonMark\Extension\Footnote\Node\FootnoteRef;
|
||||
use League\CommonMark\Extension\Footnote\Parser\AnonymousFootnoteRefParser;
|
||||
use League\CommonMark\Extension\Footnote\Parser\FootnoteParser;
|
||||
use League\CommonMark\Extension\Footnote\Parser\FootnoteRefParser;
|
||||
use League\CommonMark\Extension\Footnote\Renderer\FootnoteBackrefRenderer;
|
||||
use League\CommonMark\Extension\Footnote\Renderer\FootnoteContainerRenderer;
|
||||
use League\CommonMark\Extension\Footnote\Renderer\FootnoteRefRenderer;
|
||||
use League\CommonMark\Extension\Footnote\Renderer\FootnoteRenderer;
|
||||
|
||||
final class FootnoteExtension implements ExtensionInterface
|
||||
{
|
||||
public function register(ConfigurableEnvironmentInterface $environment)
|
||||
{
|
||||
$environment->addBlockParser(new FootnoteParser(), 51);
|
||||
$environment->addInlineParser(new AnonymousFootnoteRefParser(), 35);
|
||||
$environment->addInlineParser(new FootnoteRefParser(), 51);
|
||||
|
||||
$environment->addBlockRenderer(FootnoteContainer::class, new FootnoteContainerRenderer());
|
||||
$environment->addBlockRenderer(Footnote::class, new FootnoteRenderer());
|
||||
|
||||
$environment->addInlineRenderer(FootnoteRef::class, new FootnoteRefRenderer());
|
||||
$environment->addInlineRenderer(FootnoteBackref::class, new FootnoteBackrefRenderer());
|
||||
|
||||
$environment->addEventListener(DocumentParsedEvent::class, [new AnonymousFootnotesListener(), 'onDocumentParsed']);
|
||||
$environment->addEventListener(DocumentParsedEvent::class, [new NumberFootnotesListener(), 'onDocumentParsed']);
|
||||
$environment->addEventListener(DocumentParsedEvent::class, [new GatherFootnotesListener(), 'onDocumentParsed']);
|
||||
}
|
||||
}
|
||||
75
vendor/league/commonmark/src/Extension/Footnote/Node/Footnote.php
vendored
Normal file
75
vendor/league/commonmark/src/Extension/Footnote/Node/Footnote.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) Rezo Zero / Ambroise Maupate
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Footnote\Node;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Cursor;
|
||||
use League\CommonMark\Reference\ReferenceInterface;
|
||||
|
||||
/**
|
||||
* @method children() AbstractBlock[]
|
||||
*/
|
||||
final class Footnote extends AbstractBlock
|
||||
{
|
||||
/**
|
||||
* @var FootnoteBackref[]
|
||||
*/
|
||||
private $backrefs = [];
|
||||
|
||||
/**
|
||||
* @var ReferenceInterface
|
||||
*/
|
||||
private $reference;
|
||||
|
||||
public function __construct(ReferenceInterface $reference)
|
||||
{
|
||||
$this->reference = $reference;
|
||||
}
|
||||
|
||||
public function canContain(AbstractBlock $block): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isCode(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function matchesNextLine(Cursor $cursor): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getReference(): ReferenceInterface
|
||||
{
|
||||
return $this->reference;
|
||||
}
|
||||
|
||||
public function addBackref(FootnoteBackref $backref): self
|
||||
{
|
||||
$this->backrefs[] = $backref;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return FootnoteBackref[]
|
||||
*/
|
||||
public function getBackrefs(): array
|
||||
{
|
||||
return $this->backrefs;
|
||||
}
|
||||
}
|
||||
37
vendor/league/commonmark/src/Extension/Footnote/Node/FootnoteBackref.php
vendored
Normal file
37
vendor/league/commonmark/src/Extension/Footnote/Node/FootnoteBackref.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) Rezo Zero / Ambroise Maupate
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Footnote\Node;
|
||||
|
||||
use League\CommonMark\Inline\Element\AbstractInline;
|
||||
use League\CommonMark\Reference\ReferenceInterface;
|
||||
|
||||
/**
|
||||
* Link from the footnote on the bottom of the document back to the reference
|
||||
*/
|
||||
final class FootnoteBackref extends AbstractInline
|
||||
{
|
||||
/** @var ReferenceInterface */
|
||||
private $reference;
|
||||
|
||||
public function __construct(ReferenceInterface $reference)
|
||||
{
|
||||
$this->reference = $reference;
|
||||
}
|
||||
|
||||
public function getReference(): ReferenceInterface
|
||||
{
|
||||
return $this->reference;
|
||||
}
|
||||
}
|
||||
39
vendor/league/commonmark/src/Extension/Footnote/Node/FootnoteContainer.php
vendored
Normal file
39
vendor/league/commonmark/src/Extension/Footnote/Node/FootnoteContainer.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) Rezo Zero / Ambroise Maupate
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Footnote\Node;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Cursor;
|
||||
|
||||
/**
|
||||
* @method children() AbstractBlock[]
|
||||
*/
|
||||
final class FootnoteContainer extends AbstractBlock
|
||||
{
|
||||
public function canContain(AbstractBlock $block): bool
|
||||
{
|
||||
return $block instanceof Footnote;
|
||||
}
|
||||
|
||||
public function isCode(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function matchesNextLine(Cursor $cursor): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
56
vendor/league/commonmark/src/Extension/Footnote/Node/FootnoteRef.php
vendored
Normal file
56
vendor/league/commonmark/src/Extension/Footnote/Node/FootnoteRef.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) Rezo Zero / Ambroise Maupate
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Footnote\Node;
|
||||
|
||||
use League\CommonMark\Inline\Element\AbstractInline;
|
||||
use League\CommonMark\Reference\ReferenceInterface;
|
||||
|
||||
final class FootnoteRef extends AbstractInline
|
||||
{
|
||||
/** @var ReferenceInterface */
|
||||
private $reference;
|
||||
|
||||
/** @var string|null */
|
||||
private $content;
|
||||
|
||||
/**
|
||||
* @param ReferenceInterface $reference
|
||||
* @param string|null $content
|
||||
* @param array<mixed> $data
|
||||
*/
|
||||
public function __construct(ReferenceInterface $reference, ?string $content = null, array $data = [])
|
||||
{
|
||||
$this->reference = $reference;
|
||||
$this->content = $content;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public function getReference(): ReferenceInterface
|
||||
{
|
||||
return $this->reference;
|
||||
}
|
||||
|
||||
public function setReference(ReferenceInterface $reference): FootnoteRef
|
||||
{
|
||||
$this->reference = $reference;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getContent(): ?string
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
}
|
||||
85
vendor/league/commonmark/src/Extension/Footnote/Parser/AnonymousFootnoteRefParser.php
vendored
Normal file
85
vendor/league/commonmark/src/Extension/Footnote/Parser/AnonymousFootnoteRefParser.php
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) Rezo Zero / Ambroise Maupate
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Footnote\Parser;
|
||||
|
||||
use League\CommonMark\Extension\Footnote\Node\FootnoteRef;
|
||||
use League\CommonMark\Inline\Parser\InlineParserInterface;
|
||||
use League\CommonMark\InlineParserContext;
|
||||
use League\CommonMark\Normalizer\SlugNormalizer;
|
||||
use League\CommonMark\Normalizer\TextNormalizerInterface;
|
||||
use League\CommonMark\Reference\Reference;
|
||||
use League\CommonMark\Util\ConfigurationAwareInterface;
|
||||
use League\CommonMark\Util\ConfigurationInterface;
|
||||
|
||||
final class AnonymousFootnoteRefParser implements InlineParserInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @var ConfigurationInterface */
|
||||
private $config;
|
||||
|
||||
/** @var TextNormalizerInterface */
|
||||
private $slugNormalizer;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->slugNormalizer = new SlugNormalizer();
|
||||
}
|
||||
|
||||
public function getCharacters(): array
|
||||
{
|
||||
return ['^'];
|
||||
}
|
||||
|
||||
public function parse(InlineParserContext $inlineContext): bool
|
||||
{
|
||||
$container = $inlineContext->getContainer();
|
||||
$cursor = $inlineContext->getCursor();
|
||||
$nextChar = $cursor->peek();
|
||||
if ($nextChar !== '[') {
|
||||
return false;
|
||||
}
|
||||
$state = $cursor->saveState();
|
||||
|
||||
$m = $cursor->match('/\^\[[^\n^\]]+\]/');
|
||||
if ($m !== null) {
|
||||
if (\preg_match('#\^\[([^\]]+)\]#', $m, $matches) > 0) {
|
||||
$reference = $this->createReference($matches[1]);
|
||||
$container->appendChild(new FootnoteRef($reference, $matches[1]));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$cursor->restoreState($state);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function createReference(string $label): Reference
|
||||
{
|
||||
$refLabel = $this->slugNormalizer->normalize($label);
|
||||
$refLabel = \mb_substr($refLabel, 0, 20);
|
||||
|
||||
return new Reference(
|
||||
$refLabel,
|
||||
'#' . $this->config->get('footnote/footnote_id_prefix', 'fn:') . $refLabel,
|
||||
$label
|
||||
);
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $config): void
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
}
|
||||
63
vendor/league/commonmark/src/Extension/Footnote/Parser/FootnoteParser.php
vendored
Normal file
63
vendor/league/commonmark/src/Extension/Footnote/Parser/FootnoteParser.php
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) Rezo Zero / Ambroise Maupate
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Footnote\Parser;
|
||||
|
||||
use League\CommonMark\Block\Parser\BlockParserInterface;
|
||||
use League\CommonMark\ContextInterface;
|
||||
use League\CommonMark\Cursor;
|
||||
use League\CommonMark\Extension\Footnote\Node\Footnote;
|
||||
use League\CommonMark\Reference\Reference;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
final class FootnoteParser implements BlockParserInterface
|
||||
{
|
||||
public function parse(ContextInterface $context, Cursor $cursor): bool
|
||||
{
|
||||
if ($cursor->isIndented()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$match = RegexHelper::matchFirst(
|
||||
'/^\[\^([^\n^\]]+)\]\:\s/',
|
||||
$cursor->getLine(),
|
||||
$cursor->getNextNonSpacePosition()
|
||||
);
|
||||
|
||||
if (!$match) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
$cursor->advanceBy(\strlen($match[0]));
|
||||
$str = $cursor->getRemainder();
|
||||
\preg_replace('/^\[\^([^\n^\]]+)\]\:\s/', '', $str);
|
||||
|
||||
if (\preg_match('/^\[\^([^\n^\]]+)\]\:\s/', $match[0], $matches) > 0) {
|
||||
$context->addBlock($this->createFootnote($matches[1]));
|
||||
$context->setBlocksParsed(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function createFootnote(string $label): Footnote
|
||||
{
|
||||
return new Footnote(
|
||||
new Reference($label, $label, $label)
|
||||
);
|
||||
}
|
||||
}
|
||||
72
vendor/league/commonmark/src/Extension/Footnote/Parser/FootnoteRefParser.php
vendored
Normal file
72
vendor/league/commonmark/src/Extension/Footnote/Parser/FootnoteRefParser.php
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) Rezo Zero / Ambroise Maupate
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Footnote\Parser;
|
||||
|
||||
use League\CommonMark\Extension\Footnote\Node\FootnoteRef;
|
||||
use League\CommonMark\Inline\Parser\InlineParserInterface;
|
||||
use League\CommonMark\InlineParserContext;
|
||||
use League\CommonMark\Reference\Reference;
|
||||
use League\CommonMark\Util\ConfigurationAwareInterface;
|
||||
use League\CommonMark\Util\ConfigurationInterface;
|
||||
|
||||
final class FootnoteRefParser implements InlineParserInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @var ConfigurationInterface */
|
||||
private $config;
|
||||
|
||||
public function getCharacters(): array
|
||||
{
|
||||
return ['['];
|
||||
}
|
||||
|
||||
public function parse(InlineParserContext $inlineContext): bool
|
||||
{
|
||||
$container = $inlineContext->getContainer();
|
||||
$cursor = $inlineContext->getCursor();
|
||||
$nextChar = $cursor->peek();
|
||||
if ($nextChar !== '^') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$state = $cursor->saveState();
|
||||
|
||||
$m = $cursor->match('#\[\^([^\]]+)\]#');
|
||||
if ($m !== null) {
|
||||
if (\preg_match('#\[\^([^\]]+)\]#', $m, $matches) > 0) {
|
||||
$container->appendChild(new FootnoteRef($this->createReference($matches[1])));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$cursor->restoreState($state);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function createReference(string $label): Reference
|
||||
{
|
||||
return new Reference(
|
||||
$label,
|
||||
'#' . $this->config->get('footnote/footnote_id_prefix', 'fn:') . $label,
|
||||
$label
|
||||
);
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $config): void
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
}
|
||||
49
vendor/league/commonmark/src/Extension/Footnote/Renderer/FootnoteBackrefRenderer.php
vendored
Normal file
49
vendor/league/commonmark/src/Extension/Footnote/Renderer/FootnoteBackrefRenderer.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) Rezo Zero / Ambroise Maupate
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Footnote\Renderer;
|
||||
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\Extension\Footnote\Node\FootnoteBackref;
|
||||
use League\CommonMark\HtmlElement;
|
||||
use League\CommonMark\Inline\Element\AbstractInline;
|
||||
use League\CommonMark\Inline\Renderer\InlineRendererInterface;
|
||||
use League\CommonMark\Util\ConfigurationAwareInterface;
|
||||
use League\CommonMark\Util\ConfigurationInterface;
|
||||
|
||||
final class FootnoteBackrefRenderer implements InlineRendererInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @var ConfigurationInterface */
|
||||
private $config;
|
||||
|
||||
public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer)
|
||||
{
|
||||
if (!($inline instanceof FootnoteBackref)) {
|
||||
throw new \InvalidArgumentException('Incompatible inline type: ' . \get_class($inline));
|
||||
}
|
||||
|
||||
$attrs = $inline->getData('attributes', []);
|
||||
$attrs['class'] = $attrs['class'] ?? $this->config->get('footnote/backref_class', 'footnote-backref');
|
||||
$attrs['rev'] = 'footnote';
|
||||
$attrs['href'] = \mb_strtolower($inline->getReference()->getDestination());
|
||||
$attrs['role'] = 'doc-backlink';
|
||||
|
||||
return ' ' . new HtmlElement('a', $attrs, '↩', true);
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration)
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
}
|
||||
52
vendor/league/commonmark/src/Extension/Footnote/Renderer/FootnoteContainerRenderer.php
vendored
Normal file
52
vendor/league/commonmark/src/Extension/Footnote/Renderer/FootnoteContainerRenderer.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) Rezo Zero / Ambroise Maupate
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Footnote\Renderer;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Block\Renderer\BlockRendererInterface;
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\Extension\Footnote\Node\FootnoteContainer;
|
||||
use League\CommonMark\HtmlElement;
|
||||
use League\CommonMark\Util\ConfigurationAwareInterface;
|
||||
use League\CommonMark\Util\ConfigurationInterface;
|
||||
|
||||
final class FootnoteContainerRenderer implements BlockRendererInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @var ConfigurationInterface */
|
||||
private $config;
|
||||
|
||||
public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, bool $inTightList = false)
|
||||
{
|
||||
if (!($block instanceof FootnoteContainer)) {
|
||||
throw new \InvalidArgumentException('Incompatible block type: ' . \get_class($block));
|
||||
}
|
||||
|
||||
$attrs = $block->getData('attributes', []);
|
||||
$attrs['class'] = $attrs['class'] ?? $this->config->get('footnote/container_class', 'footnotes');
|
||||
$attrs['role'] = 'doc-endnotes';
|
||||
|
||||
$contents = new HtmlElement('ol', [], $htmlRenderer->renderBlocks($block->children()));
|
||||
if ($this->config->get('footnote/container_add_hr', true)) {
|
||||
$contents = [new HtmlElement('hr', [], null, true), $contents];
|
||||
}
|
||||
|
||||
return new HtmlElement('div', $attrs, $contents);
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration)
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
}
|
||||
62
vendor/league/commonmark/src/Extension/Footnote/Renderer/FootnoteRefRenderer.php
vendored
Normal file
62
vendor/league/commonmark/src/Extension/Footnote/Renderer/FootnoteRefRenderer.php
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) Rezo Zero / Ambroise Maupate
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Footnote\Renderer;
|
||||
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\Extension\Footnote\Node\FootnoteRef;
|
||||
use League\CommonMark\HtmlElement;
|
||||
use League\CommonMark\Inline\Element\AbstractInline;
|
||||
use League\CommonMark\Inline\Renderer\InlineRendererInterface;
|
||||
use League\CommonMark\Util\ConfigurationAwareInterface;
|
||||
use League\CommonMark\Util\ConfigurationInterface;
|
||||
|
||||
final class FootnoteRefRenderer implements InlineRendererInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @var ConfigurationInterface */
|
||||
private $config;
|
||||
|
||||
public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer)
|
||||
{
|
||||
if (!($inline instanceof FootnoteRef)) {
|
||||
throw new \InvalidArgumentException('Incompatible inline type: ' . \get_class($inline));
|
||||
}
|
||||
|
||||
$attrs = $inline->getData('attributes', []);
|
||||
$class = $attrs['class'] ?? $this->config->get('footnote/ref_class', 'footnote-ref');
|
||||
$idPrefix = $this->config->get('footnote/ref_id_prefix', 'fnref:');
|
||||
|
||||
return new HtmlElement(
|
||||
'sup',
|
||||
[
|
||||
'id' => $idPrefix . \mb_strtolower($inline->getReference()->getLabel()),
|
||||
],
|
||||
new HTMLElement(
|
||||
'a',
|
||||
[
|
||||
'class' => $class,
|
||||
'href' => \mb_strtolower($inline->getReference()->getDestination()),
|
||||
'role' => 'doc-noteref',
|
||||
],
|
||||
$inline->getReference()->getTitle()
|
||||
),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration)
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
}
|
||||
64
vendor/league/commonmark/src/Extension/Footnote/Renderer/FootnoteRenderer.php
vendored
Normal file
64
vendor/league/commonmark/src/Extension/Footnote/Renderer/FootnoteRenderer.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
* (c) Rezo Zero / Ambroise Maupate
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Footnote\Renderer;
|
||||
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Block\Renderer\BlockRendererInterface;
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\Extension\Footnote\Node\Footnote;
|
||||
use League\CommonMark\HtmlElement;
|
||||
use League\CommonMark\Util\ConfigurationAwareInterface;
|
||||
use League\CommonMark\Util\ConfigurationInterface;
|
||||
|
||||
final class FootnoteRenderer implements BlockRendererInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @var ConfigurationInterface */
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @param Footnote $block
|
||||
* @param ElementRendererInterface $htmlRenderer
|
||||
* @param bool $inTightList
|
||||
*
|
||||
* @return HtmlElement
|
||||
*/
|
||||
public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, bool $inTightList = false)
|
||||
{
|
||||
if (!($block instanceof Footnote)) {
|
||||
throw new \InvalidArgumentException('Incompatible block type: ' . \get_class($block));
|
||||
}
|
||||
|
||||
$attrs = $block->getData('attributes', []);
|
||||
$attrs['class'] = $attrs['class'] ?? $this->config->get('footnote/footnote_class', 'footnote');
|
||||
$attrs['id'] = $this->config->get('footnote/footnote_id_prefix', 'fn:') . \mb_strtolower($block->getReference()->getLabel());
|
||||
$attrs['role'] = 'doc-endnote';
|
||||
|
||||
foreach ($block->getBackrefs() as $backref) {
|
||||
$block->lastChild()->appendChild($backref);
|
||||
}
|
||||
|
||||
return new HtmlElement(
|
||||
'li',
|
||||
$attrs,
|
||||
$htmlRenderer->renderBlocks($block->children()),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration)
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
}
|
||||
31
vendor/league/commonmark/src/Extension/GithubFlavoredMarkdownExtension.php
vendored
Normal file
31
vendor/league/commonmark/src/Extension/GithubFlavoredMarkdownExtension.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension;
|
||||
|
||||
use League\CommonMark\ConfigurableEnvironmentInterface;
|
||||
use League\CommonMark\Extension\Autolink\AutolinkExtension;
|
||||
use League\CommonMark\Extension\DisallowedRawHtml\DisallowedRawHtmlExtension;
|
||||
use League\CommonMark\Extension\Strikethrough\StrikethroughExtension;
|
||||
use League\CommonMark\Extension\Table\TableExtension;
|
||||
use League\CommonMark\Extension\TaskList\TaskListExtension;
|
||||
|
||||
final class GithubFlavoredMarkdownExtension implements ExtensionInterface
|
||||
{
|
||||
public function register(ConfigurableEnvironmentInterface $environment)
|
||||
{
|
||||
$environment->addExtension(new AutolinkExtension());
|
||||
$environment->addExtension(new DisallowedRawHtmlExtension());
|
||||
$environment->addExtension(new StrikethroughExtension());
|
||||
$environment->addExtension(new TableExtension());
|
||||
$environment->addExtension(new TaskListExtension());
|
||||
}
|
||||
}
|
||||
33
vendor/league/commonmark/src/Extension/HeadingPermalink/HeadingPermalink.php
vendored
Normal file
33
vendor/league/commonmark/src/Extension/HeadingPermalink/HeadingPermalink.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\HeadingPermalink;
|
||||
|
||||
use League\CommonMark\Inline\Element\AbstractInline;
|
||||
|
||||
/**
|
||||
* Represents an anchor link within a heading
|
||||
*/
|
||||
final class HeadingPermalink extends AbstractInline
|
||||
{
|
||||
/** @var string */
|
||||
private $slug;
|
||||
|
||||
public function __construct(string $slug)
|
||||
{
|
||||
$this->slug = $slug;
|
||||
}
|
||||
|
||||
public function getSlug(): string
|
||||
{
|
||||
return $this->slug;
|
||||
}
|
||||
}
|
||||
28
vendor/league/commonmark/src/Extension/HeadingPermalink/HeadingPermalinkExtension.php
vendored
Normal file
28
vendor/league/commonmark/src/Extension/HeadingPermalink/HeadingPermalinkExtension.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\HeadingPermalink;
|
||||
|
||||
use League\CommonMark\ConfigurableEnvironmentInterface;
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\ExtensionInterface;
|
||||
|
||||
/**
|
||||
* Extension which automatically anchor links to heading elements
|
||||
*/
|
||||
final class HeadingPermalinkExtension implements ExtensionInterface
|
||||
{
|
||||
public function register(ConfigurableEnvironmentInterface $environment)
|
||||
{
|
||||
$environment->addEventListener(DocumentParsedEvent::class, new HeadingPermalinkProcessor(), -100);
|
||||
$environment->addInlineRenderer(HeadingPermalink::class, new HeadingPermalinkRenderer());
|
||||
}
|
||||
}
|
||||
147
vendor/league/commonmark/src/Extension/HeadingPermalink/HeadingPermalinkProcessor.php
vendored
Normal file
147
vendor/league/commonmark/src/Extension/HeadingPermalink/HeadingPermalinkProcessor.php
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\HeadingPermalink;
|
||||
|
||||
use League\CommonMark\Block\Element\Document;
|
||||
use League\CommonMark\Block\Element\Heading;
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Exception\InvalidOptionException;
|
||||
use League\CommonMark\Extension\HeadingPermalink\Slug\SlugGeneratorInterface as DeprecatedSlugGeneratorInterface;
|
||||
use League\CommonMark\Inline\Element\AbstractStringContainer;
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Normalizer\SlugNormalizer;
|
||||
use League\CommonMark\Normalizer\TextNormalizerInterface;
|
||||
use League\CommonMark\Util\ConfigurationAwareInterface;
|
||||
use League\CommonMark\Util\ConfigurationInterface;
|
||||
|
||||
/**
|
||||
* Searches the Document for Heading elements and adds HeadingPermalinks to each one
|
||||
*/
|
||||
final class HeadingPermalinkProcessor implements ConfigurationAwareInterface
|
||||
{
|
||||
const INSERT_BEFORE = 'before';
|
||||
const INSERT_AFTER = 'after';
|
||||
|
||||
/** @var TextNormalizerInterface|DeprecatedSlugGeneratorInterface */
|
||||
private $slugNormalizer;
|
||||
|
||||
/** @var ConfigurationInterface */
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @param TextNormalizerInterface|DeprecatedSlugGeneratorInterface|null $slugNormalizer
|
||||
*/
|
||||
public function __construct($slugNormalizer = null)
|
||||
{
|
||||
if ($slugNormalizer instanceof DeprecatedSlugGeneratorInterface) {
|
||||
@trigger_error(sprintf('Passing a %s into the %s constructor is deprecated; use a %s instead', DeprecatedSlugGeneratorInterface::class, self::class, TextNormalizerInterface::class), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$this->slugNormalizer = $slugNormalizer ?? new SlugNormalizer();
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration)
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
|
||||
public function __invoke(DocumentParsedEvent $e): void
|
||||
{
|
||||
$this->useNormalizerFromConfigurationIfProvided();
|
||||
|
||||
$walker = $e->getDocument()->walker();
|
||||
|
||||
while ($event = $walker->next()) {
|
||||
$node = $event->getNode();
|
||||
if ($node instanceof Heading && $event->isEntering()) {
|
||||
$this->addHeadingLink($node, $e->getDocument());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function useNormalizerFromConfigurationIfProvided(): void
|
||||
{
|
||||
$generator = $this->config->get('heading_permalink/slug_normalizer');
|
||||
if ($generator === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!($generator instanceof DeprecatedSlugGeneratorInterface || $generator instanceof TextNormalizerInterface)) {
|
||||
throw new InvalidOptionException('The heading_permalink/slug_normalizer option must be an instance of ' . TextNormalizerInterface::class);
|
||||
}
|
||||
|
||||
$this->slugNormalizer = $generator;
|
||||
}
|
||||
|
||||
private function addHeadingLink(Heading $heading, Document $document): void
|
||||
{
|
||||
$text = $this->getChildText($heading);
|
||||
if ($this->slugNormalizer instanceof DeprecatedSlugGeneratorInterface) {
|
||||
$slug = $this->slugNormalizer->createSlug($text);
|
||||
} else {
|
||||
$slug = $this->slugNormalizer->normalize($text, $heading);
|
||||
}
|
||||
|
||||
$slug = $this->ensureUnique($slug, $document);
|
||||
|
||||
$headingLinkAnchor = new HeadingPermalink($slug);
|
||||
|
||||
switch ($this->config->get('heading_permalink/insert', 'before')) {
|
||||
case self::INSERT_BEFORE:
|
||||
$heading->prependChild($headingLinkAnchor);
|
||||
|
||||
return;
|
||||
case self::INSERT_AFTER:
|
||||
$heading->appendChild($headingLinkAnchor);
|
||||
|
||||
return;
|
||||
default:
|
||||
throw new \RuntimeException("Invalid configuration value for heading_permalink/insert; expected 'before' or 'after'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Not needed in 2.0
|
||||
*/
|
||||
private function getChildText(Node $node): string
|
||||
{
|
||||
$text = '';
|
||||
|
||||
$walker = $node->walker();
|
||||
while ($event = $walker->next()) {
|
||||
if ($event->isEntering() && (($child = $event->getNode()) instanceof AbstractStringContainer)) {
|
||||
$text .= $child->getContent();
|
||||
}
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
private function ensureUnique(string $proposed, Document $document): string
|
||||
{
|
||||
// Quick path, it's a unique ID
|
||||
if (!isset($document->data['heading_ids'][$proposed])) {
|
||||
$document->data['heading_ids'][$proposed] = true;
|
||||
|
||||
return $proposed;
|
||||
}
|
||||
|
||||
$extension = 0;
|
||||
do {
|
||||
++$extension;
|
||||
} while (isset($document->data['heading_ids']["$proposed-$extension"]));
|
||||
|
||||
$document->data['heading_ids']["$proposed-$extension"] = true;
|
||||
|
||||
return "$proposed-$extension";
|
||||
}
|
||||
}
|
||||
72
vendor/league/commonmark/src/Extension/HeadingPermalink/HeadingPermalinkRenderer.php
vendored
Normal file
72
vendor/league/commonmark/src/Extension/HeadingPermalink/HeadingPermalinkRenderer.php
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\HeadingPermalink;
|
||||
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\HtmlElement;
|
||||
use League\CommonMark\Inline\Element\AbstractInline;
|
||||
use League\CommonMark\Inline\Renderer\InlineRendererInterface;
|
||||
use League\CommonMark\Util\ConfigurationAwareInterface;
|
||||
use League\CommonMark\Util\ConfigurationInterface;
|
||||
|
||||
/**
|
||||
* Renders the HeadingPermalink elements
|
||||
*/
|
||||
final class HeadingPermalinkRenderer implements InlineRendererInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @deprecated */
|
||||
const DEFAULT_INNER_CONTENTS = '<svg class="heading-permalink-icon" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>';
|
||||
|
||||
const DEFAULT_SYMBOL = '¶';
|
||||
|
||||
/** @var ConfigurationInterface */
|
||||
private $config;
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration)
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
|
||||
public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer)
|
||||
{
|
||||
if (!$inline instanceof HeadingPermalink) {
|
||||
throw new \InvalidArgumentException('Incompatible inline type: ' . \get_class($inline));
|
||||
}
|
||||
|
||||
$slug = $inline->getSlug();
|
||||
|
||||
$idPrefix = (string) $this->config->get('heading_permalink/id_prefix', 'user-content');
|
||||
if ($idPrefix !== '') {
|
||||
$idPrefix .= '-';
|
||||
}
|
||||
|
||||
$attrs = [
|
||||
'id' => $idPrefix . $slug,
|
||||
'href' => '#' . $slug,
|
||||
'name' => $slug,
|
||||
'class' => $this->config->get('heading_permalink/html_class', 'heading-permalink'),
|
||||
'aria-hidden' => 'true',
|
||||
'title' => $this->config->get('heading_permalink/title', 'Permalink'),
|
||||
];
|
||||
|
||||
$innerContents = $this->config->get('heading_permalink/inner_contents');
|
||||
if ($innerContents !== null) {
|
||||
@trigger_error(sprintf('The %s config option is deprecated; use %s instead', 'inner_contents', 'symbol'), E_USER_DEPRECATED);
|
||||
|
||||
return new HtmlElement('a', $attrs, $innerContents, false);
|
||||
}
|
||||
|
||||
$symbol = $this->config->get('heading_permalink/symbol', self::DEFAULT_SYMBOL);
|
||||
|
||||
return new HtmlElement('a', $attrs, \htmlspecialchars($symbol), false);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user