Upgrade framework
This commit is contained in:
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\Environment\EnvironmentBuilderInterface;
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\Attributes\Event\AttributesListener;
|
||||
use League\CommonMark\Extension\Attributes\Parser\AttributesBlockStartParser;
|
||||
use League\CommonMark\Extension\Attributes\Parser\AttributesInlineParser;
|
||||
use League\CommonMark\Extension\ExtensionInterface;
|
||||
|
||||
final class AttributesExtension implements ExtensionInterface
|
||||
{
|
||||
public function register(EnvironmentBuilderInterface $environment): void
|
||||
{
|
||||
$environment->addBlockStartParser(new AttributesBlockStartParser());
|
||||
$environment->addInlineParser(new AttributesInlineParser());
|
||||
$environment->addEventListener(DocumentParsedEvent::class, [new AttributesListener(), 'processDocument']);
|
||||
}
|
||||
}
|
||||
139
vendor/league/commonmark/src/Extension/Attributes/Event/AttributesListener.php
vendored
Normal file
139
vendor/league/commonmark/src/Extension/Attributes/Event/AttributesListener.php
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
<?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\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\Extension\CommonMark\Node\Block\FencedCode;
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\ListBlock;
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\ListItem;
|
||||
use League\CommonMark\Node\Inline\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
|
||||
{
|
||||
foreach ($event->getDocument()->iterator() as $node) {
|
||||
if (! ($node instanceof Attributes || $node instanceof AttributesInline)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
[$target, $direction] = self::findTargetAndDirection($node);
|
||||
|
||||
if ($target instanceof Node) {
|
||||
$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->set('attributes', $attributes);
|
||||
}
|
||||
|
||||
$node->detach();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attributes|AttributesInline $node
|
||||
*
|
||||
* @return array<Node|string|null>
|
||||
*/
|
||||
private static function findTargetAndDirection($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];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any previous block (sibling or parent) this might apply to
|
||||
*/
|
||||
private static function getPrevious(?Node $node = null): ?Node
|
||||
{
|
||||
if ($node instanceof Attributes) {
|
||||
if ($node->getTarget() === Attributes::TARGET_NEXT) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($node->getTarget() === Attributes::TARGET_PARENT) {
|
||||
return $node->parent();
|
||||
}
|
||||
}
|
||||
|
||||
return $node instanceof Node ? $node->previous() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any previous block (sibling or parent) this might apply to
|
||||
*/
|
||||
private static function getNext(?Node $node = null): ?Node
|
||||
{
|
||||
if ($node instanceof Attributes && $node->getTarget() !== Attributes::TARGET_NEXT) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $node instanceof Node ? $node->next() : null;
|
||||
}
|
||||
|
||||
private static function isAttributesNode(Node $node): bool
|
||||
{
|
||||
return $node instanceof Attributes || $node instanceof AttributesInline;
|
||||
}
|
||||
}
|
||||
65
vendor/league/commonmark/src/Extension/Attributes/Node/Attributes.php
vendored
Normal file
65
vendor/league/commonmark/src/Extension/Attributes/Node/Attributes.php
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
<?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\Node\Block\AbstractBlock;
|
||||
|
||||
final class Attributes extends AbstractBlock
|
||||
{
|
||||
public const TARGET_PARENT = 0;
|
||||
public const TARGET_PREVIOUS = 1;
|
||||
public const TARGET_NEXT = 2;
|
||||
|
||||
/** @var array<string, mixed> */
|
||||
private array $attributes;
|
||||
|
||||
private int $target = self::TARGET_NEXT;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $attributes
|
||||
*/
|
||||
public function __construct(array $attributes)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->attributes = $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getAttributes(): array
|
||||
{
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $attributes
|
||||
*/
|
||||
public function setAttributes(array $attributes): void
|
||||
{
|
||||
$this->attributes = $attributes;
|
||||
}
|
||||
|
||||
public function getTarget(): int
|
||||
{
|
||||
return $this->target;
|
||||
}
|
||||
|
||||
public function setTarget(int $target): void
|
||||
{
|
||||
$this->target = $target;
|
||||
}
|
||||
}
|
||||
57
vendor/league/commonmark/src/Extension/Attributes/Node/AttributesInline.php
vendored
Normal file
57
vendor/league/commonmark/src/Extension/Attributes/Node/AttributesInline.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\Node;
|
||||
|
||||
use League\CommonMark\Node\Inline\AbstractInline;
|
||||
|
||||
final class AttributesInline extends AbstractInline
|
||||
{
|
||||
/** @var array<string, mixed> */
|
||||
private array $attributes;
|
||||
|
||||
private bool $block;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $attributes
|
||||
*/
|
||||
public function __construct(array $attributes, bool $block)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->attributes = $attributes;
|
||||
$this->block = $block;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getAttributes(): array
|
||||
{
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $attributes
|
||||
*/
|
||||
public function setAttributes(array $attributes): void
|
||||
{
|
||||
$this->attributes = $attributes;
|
||||
}
|
||||
|
||||
public function isBlock(): bool
|
||||
{
|
||||
return $this->block;
|
||||
}
|
||||
}
|
||||
92
vendor/league/commonmark/src/Extension/Attributes/Parser/AttributesBlockContinueParser.php
vendored
Normal file
92
vendor/league/commonmark/src/Extension/Attributes/Parser/AttributesBlockContinueParser.php
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
<?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\Attributes;
|
||||
use League\CommonMark\Extension\Attributes\Util\AttributesHelper;
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
use League\CommonMark\Parser\Block\AbstractBlockContinueParser;
|
||||
use League\CommonMark\Parser\Block\BlockContinue;
|
||||
use League\CommonMark\Parser\Block\BlockContinueParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
|
||||
final class AttributesBlockContinueParser extends AbstractBlockContinueParser
|
||||
{
|
||||
private Attributes $block;
|
||||
|
||||
private AbstractBlock $container;
|
||||
|
||||
private bool $hasSubsequentLine = false;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $attributes The attributes identified by the block start parser
|
||||
* @param AbstractBlock $container The node we were in when these attributes were discovered
|
||||
*/
|
||||
public function __construct(array $attributes, AbstractBlock $container)
|
||||
{
|
||||
$this->block = new Attributes($attributes);
|
||||
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
public function getBlock(): AbstractBlock
|
||||
{
|
||||
return $this->block;
|
||||
}
|
||||
|
||||
public function tryContinue(Cursor $cursor, BlockContinueParserInterface $activeBlockParser): ?BlockContinue
|
||||
{
|
||||
$this->hasSubsequentLine = true;
|
||||
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
|
||||
// Does this next line also have attributes?
|
||||
$attributes = AttributesHelper::parseAttributes($cursor);
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
if ($cursor->isAtEnd() && $attributes !== []) {
|
||||
// It does! Merge them into what we parsed previously
|
||||
$this->block->setAttributes(AttributesHelper::mergeAttributes(
|
||||
$this->block->getAttributes(),
|
||||
$attributes
|
||||
));
|
||||
|
||||
// Tell the core parser we've consumed everything
|
||||
return BlockContinue::at($cursor);
|
||||
}
|
||||
|
||||
// Okay, so there are no attributes on the next line
|
||||
// If this next line is blank we know we can't target the next node, it must be a previous one
|
||||
if ($cursor->isBlank()) {
|
||||
$this->block->setTarget(Attributes::TARGET_PREVIOUS);
|
||||
}
|
||||
|
||||
return BlockContinue::none();
|
||||
}
|
||||
|
||||
public function closeBlock(): void
|
||||
{
|
||||
// Attributes appearing at the very end of the document won't have any last lines to check
|
||||
// so we can make that determination here
|
||||
if (! $this->hasSubsequentLine) {
|
||||
$this->block->setTarget(Attributes::TARGET_PREVIOUS);
|
||||
}
|
||||
|
||||
// We know this block must apply to the "previous" block, but that could be a sibling or parent,
|
||||
// so we check the containing block to see which one it might be.
|
||||
if ($this->block->getTarget() === Attributes::TARGET_PREVIOUS && $this->block->parent() === $this->container) {
|
||||
$this->block->setTarget(Attributes::TARGET_PARENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
40
vendor/league/commonmark/src/Extension/Attributes/Parser/AttributesBlockStartParser.php
vendored
Normal file
40
vendor/league/commonmark/src/Extension/Attributes/Parser/AttributesBlockStartParser.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>
|
||||
* (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\Util\AttributesHelper;
|
||||
use League\CommonMark\Parser\Block\BlockStart;
|
||||
use League\CommonMark\Parser\Block\BlockStartParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
use League\CommonMark\Parser\MarkdownParserStateInterface;
|
||||
|
||||
final class AttributesBlockStartParser implements BlockStartParserInterface
|
||||
{
|
||||
public function tryStart(Cursor $cursor, MarkdownParserStateInterface $parserState): ?BlockStart
|
||||
{
|
||||
$originalPosition = $cursor->getPosition();
|
||||
$attributes = AttributesHelper::parseAttributes($cursor);
|
||||
|
||||
if ($attributes === [] && $originalPosition === $cursor->getPosition()) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
if ($cursor->getNextNonSpaceCharacter() !== null) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
return BlockStart::of(new AttributesBlockContinueParser($attributes, $parserState->getActiveBlockParser()->getBlock()))->at($cursor);
|
||||
}
|
||||
}
|
||||
54
vendor/league/commonmark/src/Extension/Attributes/Parser/AttributesInlineParser.php
vendored
Normal file
54
vendor/league/commonmark/src/Extension/Attributes/Parser/AttributesInlineParser.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?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\Node\StringContainerInterface;
|
||||
use League\CommonMark\Parser\Inline\InlineParserInterface;
|
||||
use League\CommonMark\Parser\Inline\InlineParserMatch;
|
||||
use League\CommonMark\Parser\InlineParserContext;
|
||||
|
||||
final class AttributesInlineParser implements InlineParserInterface
|
||||
{
|
||||
public function getMatchDefinition(): InlineParserMatch
|
||||
{
|
||||
return InlineParserMatch::string('{');
|
||||
}
|
||||
|
||||
public function parse(InlineParserContext $inlineContext): bool
|
||||
{
|
||||
$cursor = $inlineContext->getCursor();
|
||||
$char = (string) $cursor->peek(-1);
|
||||
|
||||
$attributes = AttributesHelper::parseAttributes($cursor);
|
||||
if ($attributes === []) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($char === ' ' && ($prev = $inlineContext->getContainer()->lastChild()) instanceof StringContainerInterface) {
|
||||
$prev->setLiteral(\rtrim($prev->getLiteral(), ' '));
|
||||
}
|
||||
|
||||
if ($char === '') {
|
||||
$cursor->advanceToNextNonSpaceOrNewline();
|
||||
}
|
||||
|
||||
$node = new AttributesInline($attributes, $char === ' ' || $char === '');
|
||||
$inlineContext->getContainer()->appendChild($node);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
136
vendor/league/commonmark/src/Extension/Attributes/Util/AttributesHelper.php
vendored
Normal file
136
vendor/league/commonmark/src/Extension/Attributes/Util/AttributesHelper.php
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
<?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\Node\Node;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class AttributesHelper
|
||||
{
|
||||
private const SINGLE_ATTRIBUTE = '\s*([.#][_a-z0-9-]+|' . RegexHelper::PARTIAL_ATTRIBUTENAME . RegexHelper::PARTIAL_ATTRIBUTEVALUESPEC . ')\s*';
|
||||
private const ATTRIBUTE_LIST = '/^{:?(' . self::SINGLE_ATTRIBUTE . ')+}/i';
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public static function parseAttributes(Cursor $cursor): array
|
||||
{
|
||||
$state = $cursor->saveState();
|
||||
$cursor->advanceToNextNonSpaceOrNewline();
|
||||
|
||||
// Quick check to see if we might have attributes
|
||||
if ($cursor->getCharacter() !== '{') {
|
||||
$cursor->restoreState($state);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
// Attempt to match the entire attribute list expression
|
||||
// While this is less performant than checking for '{' now and '}' later, it simplifies
|
||||
// matching individual attributes since they won't need to look ahead for the closing '}'
|
||||
// while dealing with the fact that attributes can technically contain curly braces.
|
||||
// So we'll just match the start and end braces up front.
|
||||
$attributeExpression = $cursor->match(self::ATTRIBUTE_LIST);
|
||||
if ($attributeExpression === null) {
|
||||
$cursor->restoreState($state);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
// Trim the leading '{' or '{:' and the trailing '}'
|
||||
$attributeExpression = \ltrim(\substr($attributeExpression, 1, -1), ':');
|
||||
$attributeCursor = new Cursor($attributeExpression);
|
||||
|
||||
/** @var array<string, mixed> $attributes */
|
||||
$attributes = [];
|
||||
while ($attribute = \trim((string) $attributeCursor->match('/^' . self::SINGLE_ATTRIBUTE . '/i'))) {
|
||||
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 (isset($attributes['class'])) {
|
||||
$attributes['class'] = \implode(' ', (array) $attributes['class']);
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node|array<string, mixed> $attributes1
|
||||
* @param Node|array<string, mixed> $attributes2
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public static function mergeAttributes($attributes1, $attributes2): array
|
||||
{
|
||||
$attributes = [];
|
||||
foreach ([$attributes1, $attributes2] as $arg) {
|
||||
if ($arg instanceof Node) {
|
||||
$arg = $arg->data->get('attributes');
|
||||
}
|
||||
|
||||
/** @var array<string, mixed> $arg */
|
||||
$arg = (array) $arg;
|
||||
if (isset($arg['class'])) {
|
||||
if (\is_string($arg['class'])) {
|
||||
$arg['class'] = \array_filter(\explode(' ', \trim($arg['class'])));
|
||||
}
|
||||
|
||||
foreach ($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;
|
||||
}
|
||||
}
|
||||
26
vendor/league/commonmark/src/Extension/Autolink/AutolinkExtension.php
vendored
Normal file
26
vendor/league/commonmark/src/Extension/Autolink/AutolinkExtension.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?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\Extension\Autolink;
|
||||
|
||||
use League\CommonMark\Environment\EnvironmentBuilderInterface;
|
||||
use League\CommonMark\Extension\ExtensionInterface;
|
||||
|
||||
final class AutolinkExtension implements ExtensionInterface
|
||||
{
|
||||
public function register(EnvironmentBuilderInterface $environment): void
|
||||
{
|
||||
$environment->addInlineParser(new EmailAutolinkParser());
|
||||
$environment->addInlineParser(new UrlAutolinkParser());
|
||||
}
|
||||
}
|
||||
48
vendor/league/commonmark/src/Extension/Autolink/EmailAutolinkParser.php
vendored
Normal file
48
vendor/league/commonmark/src/Extension/Autolink/EmailAutolinkParser.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?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\Extension\Autolink;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\Link;
|
||||
use League\CommonMark\Parser\Inline\InlineParserInterface;
|
||||
use League\CommonMark\Parser\Inline\InlineParserMatch;
|
||||
use League\CommonMark\Parser\InlineParserContext;
|
||||
|
||||
final class EmailAutolinkParser implements InlineParserInterface
|
||||
{
|
||||
private const REGEX = '[A-Za-z0-9.\-_+]+@[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_.]+';
|
||||
|
||||
public function getMatchDefinition(): InlineParserMatch
|
||||
{
|
||||
return InlineParserMatch::regex(self::REGEX);
|
||||
}
|
||||
|
||||
public function parse(InlineParserContext $inlineContext): bool
|
||||
{
|
||||
$email = $inlineContext->getFullMatch();
|
||||
// The last character cannot be - or _
|
||||
if (\in_array(\substr($email, -1), ['-', '_'], true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Does the URL end with punctuation that should be stripped?
|
||||
if (\substr($email, -1) === '.') {
|
||||
$email = \substr($email, 0, -1);
|
||||
}
|
||||
|
||||
$inlineContext->getCursor()->advanceBy(\strlen($email));
|
||||
$inlineContext->getContainer()->appendChild(new Link('mailto:' . $email, $email));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
140
vendor/league/commonmark/src/Extension/Autolink/UrlAutolinkParser.php
vendored
Normal file
140
vendor/league/commonmark/src/Extension/Autolink/UrlAutolinkParser.php
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
<?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\Extension\Autolink;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\Link;
|
||||
use League\CommonMark\Parser\Inline\InlineParserInterface;
|
||||
use League\CommonMark\Parser\Inline\InlineParserMatch;
|
||||
use League\CommonMark\Parser\InlineParserContext;
|
||||
|
||||
final class UrlAutolinkParser implements InlineParserInterface
|
||||
{
|
||||
private const ALLOWED_AFTER = [null, ' ', "\t", "\n", "\x0b", "\x0c", "\x0d", '*', '_', '~', '('];
|
||||
|
||||
// RegEx adapted from https://github.com/symfony/symfony/blob/4.2/src/Symfony/Component/Validator/Constraints/UrlValidator.php
|
||||
private const REGEX = '~
|
||||
(
|
||||
# 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[]
|
||||
*
|
||||
* @psalm-readonly
|
||||
*/
|
||||
private array $prefixes = ['www'];
|
||||
|
||||
/** @psalm-readonly */
|
||||
private string $finalRegex;
|
||||
|
||||
/**
|
||||
* @param array<int, string> $allowedProtocols
|
||||
*/
|
||||
public function __construct(array $allowedProtocols = ['http', 'https', 'ftp'])
|
||||
{
|
||||
$this->finalRegex = \sprintf(self::REGEX, \implode('|', $allowedProtocols));
|
||||
|
||||
foreach ($allowedProtocols as $protocol) {
|
||||
$this->prefixes[] = $protocol . '://';
|
||||
}
|
||||
}
|
||||
|
||||
public function getMatchDefinition(): InlineParserMatch
|
||||
{
|
||||
return InlineParserMatch::oneOf(...$this->prefixes);
|
||||
}
|
||||
|
||||
public function parse(InlineParserContext $inlineContext): bool
|
||||
{
|
||||
$cursor = $inlineContext->getCursor();
|
||||
|
||||
// Autolinks can only come at the beginning of a line, after whitespace, or certain delimiting characters
|
||||
$previousChar = $cursor->peek(-1);
|
||||
if (! \in_array($previousChar, self::ALLOWED_AFTER, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if we have a valid URL
|
||||
if (! \preg_match($this->finalRegex, $cursor->getRemainder(), $matches)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$url = $matches[0];
|
||||
|
||||
// Does the URL end with punctuation that should be stripped?
|
||||
if (\preg_match('/(.+?)([?!.,:*_~]+)$/', $url, $matches)) {
|
||||
// Add the punctuation later
|
||||
$url = $matches[1];
|
||||
}
|
||||
|
||||
// Does the URL end with something that looks like an entity reference?
|
||||
if (\preg_match('/(.+)(&[A-Za-z0-9]+;)$/', $url, $matches)) {
|
||||
$url = $matches[1];
|
||||
}
|
||||
|
||||
// Does the URL need unmatched parens chopped off?
|
||||
if (\substr($url, -1) === ')' && ($diff = self::diffParens($url)) > 0) {
|
||||
$url = \substr($url, 0, -$diff);
|
||||
}
|
||||
|
||||
$cursor->advanceBy(\mb_strlen($url, 'UTF-8'));
|
||||
|
||||
// Auto-prefix 'http://' onto 'www' URLs
|
||||
if (\substr($url, 0, 4) === 'www.') {
|
||||
$inlineContext->getContainer()->appendChild(new Link('http://' . $url, $url));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$inlineContext->getContainer()->appendChild(new Link($url, $url));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-pure
|
||||
*/
|
||||
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['('];
|
||||
}
|
||||
}
|
||||
92
vendor/league/commonmark/src/Extension/CommonMark/CommonMarkCoreExtension.php
vendored
Normal file
92
vendor/league/commonmark/src/Extension/CommonMark/CommonMarkCoreExtension.php
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark;
|
||||
|
||||
use League\CommonMark\Environment\EnvironmentBuilderInterface;
|
||||
use League\CommonMark\Extension\CommonMark\Delimiter\Processor\EmphasisDelimiterProcessor;
|
||||
use League\CommonMark\Extension\ConfigurableExtensionInterface;
|
||||
use League\CommonMark\Node as CoreNode;
|
||||
use League\CommonMark\Parser as CoreParser;
|
||||
use League\CommonMark\Renderer as CoreRenderer;
|
||||
use League\Config\ConfigurationBuilderInterface;
|
||||
use Nette\Schema\Expect;
|
||||
|
||||
final class CommonMarkCoreExtension implements ConfigurableExtensionInterface
|
||||
{
|
||||
public function configureSchema(ConfigurationBuilderInterface $builder): void
|
||||
{
|
||||
$builder->addSchema('commonmark', Expect::structure([
|
||||
'use_asterisk' => Expect::bool(true),
|
||||
'use_underscore' => Expect::bool(true),
|
||||
'enable_strong' => Expect::bool(true),
|
||||
'enable_em' => Expect::bool(true),
|
||||
'unordered_list_markers' => Expect::listOf('string')->min(1)->default(['*', '+', '-'])->mergeDefaults(false),
|
||||
]));
|
||||
}
|
||||
|
||||
// phpcs:disable Generic.Functions.FunctionCallArgumentSpacing.TooMuchSpaceAfterComma,Squiz.WhiteSpace.SemicolonSpacing.Incorrect
|
||||
public function register(EnvironmentBuilderInterface $environment): void
|
||||
{
|
||||
$environment
|
||||
->addBlockStartParser(new Parser\Block\BlockQuoteStartParser(), 70)
|
||||
->addBlockStartParser(new Parser\Block\HeadingStartParser(), 60)
|
||||
->addBlockStartParser(new Parser\Block\FencedCodeStartParser(), 50)
|
||||
->addBlockStartParser(new Parser\Block\HtmlBlockStartParser(), 40)
|
||||
->addBlockStartParser(new Parser\Block\ThematicBreakStartParser(), 20)
|
||||
->addBlockStartParser(new Parser\Block\ListBlockStartParser(), 10)
|
||||
->addBlockStartParser(new Parser\Block\IndentedCodeStartParser(), -100)
|
||||
|
||||
->addInlineParser(new CoreParser\Inline\NewlineParser(), 200)
|
||||
->addInlineParser(new Parser\Inline\BacktickParser(), 150)
|
||||
->addInlineParser(new Parser\Inline\EscapableParser(), 80)
|
||||
->addInlineParser(new Parser\Inline\EntityParser(), 70)
|
||||
->addInlineParser(new Parser\Inline\AutolinkParser(), 50)
|
||||
->addInlineParser(new Parser\Inline\HtmlInlineParser(), 40)
|
||||
->addInlineParser(new Parser\Inline\CloseBracketParser(), 30)
|
||||
->addInlineParser(new Parser\Inline\OpenBracketParser(), 20)
|
||||
->addInlineParser(new Parser\Inline\BangParser(), 10)
|
||||
|
||||
->addRenderer(Node\Block\BlockQuote::class, new Renderer\Block\BlockQuoteRenderer(), 0)
|
||||
->addRenderer(CoreNode\Block\Document::class, new CoreRenderer\Block\DocumentRenderer(), 0)
|
||||
->addRenderer(Node\Block\FencedCode::class, new Renderer\Block\FencedCodeRenderer(), 0)
|
||||
->addRenderer(Node\Block\Heading::class, new Renderer\Block\HeadingRenderer(), 0)
|
||||
->addRenderer(Node\Block\HtmlBlock::class, new Renderer\Block\HtmlBlockRenderer(), 0)
|
||||
->addRenderer(Node\Block\IndentedCode::class, new Renderer\Block\IndentedCodeRenderer(), 0)
|
||||
->addRenderer(Node\Block\ListBlock::class, new Renderer\Block\ListBlockRenderer(), 0)
|
||||
->addRenderer(Node\Block\ListItem::class, new Renderer\Block\ListItemRenderer(), 0)
|
||||
->addRenderer(CoreNode\Block\Paragraph::class, new CoreRenderer\Block\ParagraphRenderer(), 0)
|
||||
->addRenderer(Node\Block\ThematicBreak::class, new Renderer\Block\ThematicBreakRenderer(), 0)
|
||||
|
||||
->addRenderer(Node\Inline\Code::class, new Renderer\Inline\CodeRenderer(), 0)
|
||||
->addRenderer(Node\Inline\Emphasis::class, new Renderer\Inline\EmphasisRenderer(), 0)
|
||||
->addRenderer(Node\Inline\HtmlInline::class, new Renderer\Inline\HtmlInlineRenderer(), 0)
|
||||
->addRenderer(Node\Inline\Image::class, new Renderer\Inline\ImageRenderer(), 0)
|
||||
->addRenderer(Node\Inline\Link::class, new Renderer\Inline\LinkRenderer(), 0)
|
||||
->addRenderer(CoreNode\Inline\Newline::class, new CoreRenderer\Inline\NewlineRenderer(), 0)
|
||||
->addRenderer(Node\Inline\Strong::class, new Renderer\Inline\StrongRenderer(), 0)
|
||||
->addRenderer(CoreNode\Inline\Text::class, new CoreRenderer\Inline\TextRenderer(), 0)
|
||||
;
|
||||
|
||||
if ($environment->getConfiguration()->get('commonmark/use_asterisk')) {
|
||||
$environment->addDelimiterProcessor(new EmphasisDelimiterProcessor('*'));
|
||||
}
|
||||
|
||||
if ($environment->getConfiguration()->get('commonmark/use_underscore')) {
|
||||
$environment->addDelimiterProcessor(new EmphasisDelimiterProcessor('_'));
|
||||
}
|
||||
}
|
||||
}
|
||||
108
vendor/league/commonmark/src/Extension/CommonMark/Delimiter/Processor/EmphasisDelimiterProcessor.php
vendored
Normal file
108
vendor/league/commonmark/src/Extension/CommonMark/Delimiter/Processor/EmphasisDelimiterProcessor.php
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\Extension\CommonMark\Delimiter\Processor;
|
||||
|
||||
use League\CommonMark\Delimiter\DelimiterInterface;
|
||||
use League\CommonMark\Delimiter\Processor\DelimiterProcessorInterface;
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\Emphasis;
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\Strong;
|
||||
use League\CommonMark\Node\Inline\AbstractStringContainer;
|
||||
use League\Config\ConfigurationAwareInterface;
|
||||
use League\Config\ConfigurationInterface;
|
||||
|
||||
final class EmphasisDelimiterProcessor implements DelimiterProcessorInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @psalm-readonly */
|
||||
private string $char;
|
||||
|
||||
/** @psalm-readonly-allow-private-mutation */
|
||||
private ConfigurationInterface $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->config->get('commonmark/enable_strong')) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($this->config->get('commonmark/enable_em')) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function process(AbstractStringContainer $opener, AbstractStringContainer $closer, int $delimiterUse): void
|
||||
{
|
||||
if ($delimiterUse === 1) {
|
||||
$emphasis = new Emphasis($this->char);
|
||||
} elseif ($delimiterUse === 2) {
|
||||
$emphasis = new Strong($this->char . $this->char);
|
||||
} 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): void
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
}
|
||||
20
vendor/league/commonmark/src/Extension/CommonMark/Node/Block/BlockQuote.php
vendored
Normal file
20
vendor/league/commonmark/src/Extension/CommonMark/Node/Block/BlockQuote.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?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\Extension\CommonMark\Node\Block;
|
||||
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
|
||||
class BlockQuote extends AbstractBlock
|
||||
{
|
||||
}
|
||||
100
vendor/league/commonmark/src/Extension/CommonMark/Node/Block/FencedCode.php
vendored
Normal file
100
vendor/league/commonmark/src/Extension/CommonMark/Node/Block/FencedCode.php
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Node\Block;
|
||||
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
use League\CommonMark\Node\StringContainerInterface;
|
||||
|
||||
final class FencedCode extends AbstractBlock implements StringContainerInterface
|
||||
{
|
||||
private ?string $info = null;
|
||||
|
||||
private string $literal = '';
|
||||
|
||||
private int $length;
|
||||
|
||||
private string $char;
|
||||
|
||||
private int $offset;
|
||||
|
||||
public function __construct(int $length, string $char, int $offset)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->length = $length;
|
||||
$this->char = $char;
|
||||
$this->offset = $offset;
|
||||
}
|
||||
|
||||
public function getInfo(): ?string
|
||||
{
|
||||
return $this->info;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getInfoWords(): array
|
||||
{
|
||||
return \preg_split('/\s+/', $this->info ?? '') ?: [];
|
||||
}
|
||||
|
||||
public function setInfo(string $info): void
|
||||
{
|
||||
$this->info = $info;
|
||||
}
|
||||
|
||||
public function getLiteral(): string
|
||||
{
|
||||
return $this->literal;
|
||||
}
|
||||
|
||||
public function setLiteral(string $literal): void
|
||||
{
|
||||
$this->literal = $literal;
|
||||
}
|
||||
|
||||
public function getChar(): string
|
||||
{
|
||||
return $this->char;
|
||||
}
|
||||
|
||||
public function setChar(string $char): void
|
||||
{
|
||||
$this->char = $char;
|
||||
}
|
||||
|
||||
public function getLength(): int
|
||||
{
|
||||
return $this->length;
|
||||
}
|
||||
|
||||
public function setLength(int $length): void
|
||||
{
|
||||
$this->length = $length;
|
||||
}
|
||||
|
||||
public function getOffset(): int
|
||||
{
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
public function setOffset(int $offset): void
|
||||
{
|
||||
$this->offset = $offset;
|
||||
}
|
||||
}
|
||||
41
vendor/league/commonmark/src/Extension/CommonMark/Node/Block/Heading.php
vendored
Normal file
41
vendor/league/commonmark/src/Extension/CommonMark/Node/Block/Heading.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Node\Block;
|
||||
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
|
||||
final class Heading extends AbstractBlock
|
||||
{
|
||||
private int $level;
|
||||
|
||||
public function __construct(int $level)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->level = $level;
|
||||
}
|
||||
|
||||
public function getLevel(): int
|
||||
{
|
||||
return $this->level;
|
||||
}
|
||||
|
||||
public function setLevel(int $level): void
|
||||
{
|
||||
$this->level = $level;
|
||||
}
|
||||
}
|
||||
79
vendor/league/commonmark/src/Extension/CommonMark/Node/Block/HtmlBlock.php
vendored
Normal file
79
vendor/league/commonmark/src/Extension/CommonMark/Node/Block/HtmlBlock.php
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
<?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\Extension\CommonMark\Node\Block;
|
||||
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
use League\CommonMark\Node\RawMarkupContainerInterface;
|
||||
|
||||
final class HtmlBlock extends AbstractBlock implements RawMarkupContainerInterface
|
||||
{
|
||||
// Any changes to these constants should be reflected in .phpstorm.meta.php
|
||||
public const TYPE_1_CODE_CONTAINER = 1;
|
||||
public const TYPE_2_COMMENT = 2;
|
||||
public const TYPE_3 = 3;
|
||||
public const TYPE_4 = 4;
|
||||
public const TYPE_5_CDATA = 5;
|
||||
public const TYPE_6_BLOCK_ELEMENT = 6;
|
||||
public const TYPE_7_MISC_ELEMENT = 7;
|
||||
|
||||
/**
|
||||
* @psalm-var self::TYPE_* $type
|
||||
* @phpstan-var self::TYPE_* $type
|
||||
*/
|
||||
private int $type;
|
||||
|
||||
private string $literal = '';
|
||||
|
||||
/**
|
||||
* @psalm-param self::TYPE_* $type
|
||||
*
|
||||
* @phpstan-param self::TYPE_* $type
|
||||
*/
|
||||
public function __construct(int $type)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-return self::TYPE_*
|
||||
*
|
||||
* @phpstan-return self::TYPE_*
|
||||
*/
|
||||
public function getType(): int
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-param self::TYPE_* $type
|
||||
*
|
||||
* @phpstan-param self::TYPE_* $type
|
||||
*/
|
||||
public function setType(int $type): void
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
public function getLiteral(): string
|
||||
{
|
||||
return $this->literal;
|
||||
}
|
||||
|
||||
public function setLiteral(string $literal): void
|
||||
{
|
||||
$this->literal = $literal;
|
||||
}
|
||||
}
|
||||
32
vendor/league/commonmark/src/Extension/CommonMark/Node/Block/IndentedCode.php
vendored
Normal file
32
vendor/league/commonmark/src/Extension/CommonMark/Node/Block/IndentedCode.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?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\Extension\CommonMark\Node\Block;
|
||||
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
use League\CommonMark\Node\StringContainerInterface;
|
||||
|
||||
final class IndentedCode extends AbstractBlock implements StringContainerInterface
|
||||
{
|
||||
private string $literal = '';
|
||||
|
||||
public function getLiteral(): string
|
||||
{
|
||||
return $this->literal;
|
||||
}
|
||||
|
||||
public function setLiteral(string $literal): void
|
||||
{
|
||||
$this->literal = $literal;
|
||||
}
|
||||
}
|
||||
56
vendor/league/commonmark/src/Extension/CommonMark/Node/Block/ListBlock.php
vendored
Normal file
56
vendor/league/commonmark/src/Extension/CommonMark/Node/Block/ListBlock.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Node\Block;
|
||||
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
use League\CommonMark\Node\Block\TightBlockInterface;
|
||||
|
||||
class ListBlock extends AbstractBlock implements TightBlockInterface
|
||||
{
|
||||
public const TYPE_BULLET = 'bullet';
|
||||
public const TYPE_ORDERED = 'ordered';
|
||||
|
||||
public const DELIM_PERIOD = 'period';
|
||||
public const DELIM_PAREN = 'paren';
|
||||
|
||||
protected bool $tight = false;
|
||||
|
||||
/** @psalm-readonly */
|
||||
protected ListData $listData;
|
||||
|
||||
public function __construct(ListData $listData)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->listData = $listData;
|
||||
}
|
||||
|
||||
public function getListData(): ListData
|
||||
{
|
||||
return $this->listData;
|
||||
}
|
||||
|
||||
public function isTight(): bool
|
||||
{
|
||||
return $this->tight;
|
||||
}
|
||||
|
||||
public function setTight(bool $tight): void
|
||||
{
|
||||
$this->tight = $tight;
|
||||
}
|
||||
}
|
||||
47
vendor/league/commonmark/src/Extension/CommonMark/Node/Block/ListData.php
vendored
Normal file
47
vendor/league/commonmark/src/Extension/CommonMark/Node/Block/ListData.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Node\Block;
|
||||
|
||||
class ListData
|
||||
{
|
||||
public ?int $start = null;
|
||||
|
||||
public int $padding = 0;
|
||||
|
||||
/**
|
||||
* @psalm-var ListBlock::TYPE_*
|
||||
* @phpstan-var ListBlock::TYPE_*
|
||||
*/
|
||||
public string $type;
|
||||
|
||||
/**
|
||||
* @psalm-var ListBlock::DELIM_*|null
|
||||
* @phpstan-var ListBlock::DELIM_*|null
|
||||
*/
|
||||
public ?string $delimiter = null;
|
||||
|
||||
public ?string $bulletChar = null;
|
||||
|
||||
public int $markerOffset;
|
||||
|
||||
public function equals(ListData $data): bool
|
||||
{
|
||||
return $this->type === $data->type &&
|
||||
$this->delimiter === $data->delimiter &&
|
||||
$this->bulletChar === $data->bulletChar;
|
||||
}
|
||||
}
|
||||
37
vendor/league/commonmark/src/Extension/CommonMark/Node/Block/ListItem.php
vendored
Normal file
37
vendor/league/commonmark/src/Extension/CommonMark/Node/Block/ListItem.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Node\Block;
|
||||
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
|
||||
class ListItem extends AbstractBlock
|
||||
{
|
||||
/** @psalm-readonly */
|
||||
protected ListData $listData;
|
||||
|
||||
public function __construct(ListData $listData)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->listData = $listData;
|
||||
}
|
||||
|
||||
public function getListData(): ListData
|
||||
{
|
||||
return $this->listData;
|
||||
}
|
||||
}
|
||||
20
vendor/league/commonmark/src/Extension/CommonMark/Node/Block/ThematicBreak.php
vendored
Normal file
20
vendor/league/commonmark/src/Extension/CommonMark/Node/Block/ThematicBreak.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?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\Extension\CommonMark\Node\Block;
|
||||
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
|
||||
class ThematicBreak extends AbstractBlock
|
||||
{
|
||||
}
|
||||
41
vendor/league/commonmark/src/Extension/CommonMark/Node/Inline/AbstractWebResource.php
vendored
Normal file
41
vendor/league/commonmark/src/Extension/CommonMark/Node/Inline/AbstractWebResource.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Node\Inline;
|
||||
|
||||
use League\CommonMark\Node\Inline\AbstractInline;
|
||||
|
||||
abstract class AbstractWebResource extends AbstractInline
|
||||
{
|
||||
protected string $url;
|
||||
|
||||
public function __construct(string $url)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
public function getUrl(): string
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function setUrl(string $url): void
|
||||
{
|
||||
$this->url = $url;
|
||||
}
|
||||
}
|
||||
23
vendor/league/commonmark/src/Extension/CommonMark/Node/Inline/Code.php
vendored
Normal file
23
vendor/league/commonmark/src/Extension/CommonMark/Node/Inline/Code.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Node\Inline;
|
||||
|
||||
use League\CommonMark\Node\Inline\AbstractStringContainer;
|
||||
|
||||
class Code extends AbstractStringContainer
|
||||
{
|
||||
}
|
||||
42
vendor/league/commonmark/src/Extension/CommonMark/Node/Inline/Emphasis.php
vendored
Normal file
42
vendor/league/commonmark/src/Extension/CommonMark/Node/Inline/Emphasis.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Node\Inline;
|
||||
|
||||
use League\CommonMark\Node\Inline\AbstractInline;
|
||||
use League\CommonMark\Node\Inline\DelimitedInterface;
|
||||
|
||||
final class Emphasis extends AbstractInline implements DelimitedInterface
|
||||
{
|
||||
private string $delimiter;
|
||||
|
||||
public function __construct(string $delimiter = '_')
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->delimiter = $delimiter;
|
||||
}
|
||||
|
||||
public function getOpeningDelimiter(): string
|
||||
{
|
||||
return $this->delimiter;
|
||||
}
|
||||
|
||||
public function getClosingDelimiter(): string
|
||||
{
|
||||
return $this->delimiter;
|
||||
}
|
||||
}
|
||||
24
vendor/league/commonmark/src/Extension/CommonMark/Node/Inline/HtmlInline.php
vendored
Normal file
24
vendor/league/commonmark/src/Extension/CommonMark/Node/Inline/HtmlInline.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Node\Inline;
|
||||
|
||||
use League\CommonMark\Node\Inline\AbstractStringContainer;
|
||||
use League\CommonMark\Node\RawMarkupContainerInterface;
|
||||
|
||||
final class HtmlInline extends AbstractStringContainer implements RawMarkupContainerInterface
|
||||
{
|
||||
}
|
||||
49
vendor/league/commonmark/src/Extension/CommonMark/Node/Inline/Image.php
vendored
Normal file
49
vendor/league/commonmark/src/Extension/CommonMark/Node/Inline/Image.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Node\Inline;
|
||||
|
||||
use League\CommonMark\Node\Inline\Text;
|
||||
|
||||
class Image extends AbstractWebResource
|
||||
{
|
||||
protected ?string $title = null;
|
||||
|
||||
public function __construct(string $url, ?string $label = null, ?string $title = null)
|
||||
{
|
||||
parent::__construct($url);
|
||||
|
||||
if ($label !== null && $label !== '') {
|
||||
$this->appendChild(new Text($label));
|
||||
}
|
||||
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
public function getTitle(): ?string
|
||||
{
|
||||
if ($this->title === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function setTitle(?string $title): void
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
}
|
||||
49
vendor/league/commonmark/src/Extension/CommonMark/Node/Inline/Link.php
vendored
Normal file
49
vendor/league/commonmark/src/Extension/CommonMark/Node/Inline/Link.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Node\Inline;
|
||||
|
||||
use League\CommonMark\Node\Inline\Text;
|
||||
|
||||
class Link extends AbstractWebResource
|
||||
{
|
||||
protected ?string $title = null;
|
||||
|
||||
public function __construct(string $url, ?string $label = null, ?string $title = null)
|
||||
{
|
||||
parent::__construct($url);
|
||||
|
||||
if ($label !== null && $label !== '') {
|
||||
$this->appendChild(new Text($label));
|
||||
}
|
||||
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
public function getTitle(): ?string
|
||||
{
|
||||
if ($this->title === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function setTitle(?string $title): void
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
}
|
||||
42
vendor/league/commonmark/src/Extension/CommonMark/Node/Inline/Strong.php
vendored
Normal file
42
vendor/league/commonmark/src/Extension/CommonMark/Node/Inline/Strong.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Node\Inline;
|
||||
|
||||
use League\CommonMark\Node\Inline\AbstractInline;
|
||||
use League\CommonMark\Node\Inline\DelimitedInterface;
|
||||
|
||||
final class Strong extends AbstractInline implements DelimitedInterface
|
||||
{
|
||||
private string $delimiter;
|
||||
|
||||
public function __construct(string $delimiter = '**')
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->delimiter = $delimiter;
|
||||
}
|
||||
|
||||
public function getOpeningDelimiter(): string
|
||||
{
|
||||
return $this->delimiter;
|
||||
}
|
||||
|
||||
public function getClosingDelimiter(): string
|
||||
{
|
||||
return $this->delimiter;
|
||||
}
|
||||
}
|
||||
60
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/BlockQuoteParser.php
vendored
Normal file
60
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/BlockQuoteParser.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?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\Extension\CommonMark\Parser\Block;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\BlockQuote;
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
use League\CommonMark\Parser\Block\AbstractBlockContinueParser;
|
||||
use League\CommonMark\Parser\Block\BlockContinue;
|
||||
use League\CommonMark\Parser\Block\BlockContinueParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
|
||||
final class BlockQuoteParser extends AbstractBlockContinueParser
|
||||
{
|
||||
/** @psalm-readonly */
|
||||
private BlockQuote $block;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->block = new BlockQuote();
|
||||
}
|
||||
|
||||
public function getBlock(): BlockQuote
|
||||
{
|
||||
return $this->block;
|
||||
}
|
||||
|
||||
public function isContainer(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canContain(AbstractBlock $childBlock): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function tryContinue(Cursor $cursor, BlockContinueParserInterface $activeBlockParser): ?BlockContinue
|
||||
{
|
||||
if (! $cursor->isIndented() && $cursor->getNextNonSpaceCharacter() === '>') {
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
$cursor->advanceBy(1);
|
||||
$cursor->advanceBySpaceOrTab();
|
||||
|
||||
return BlockContinue::at($cursor);
|
||||
}
|
||||
|
||||
return BlockContinue::none();
|
||||
}
|
||||
}
|
||||
39
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/BlockQuoteStartParser.php
vendored
Normal file
39
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/BlockQuoteStartParser.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?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\Extension\CommonMark\Parser\Block;
|
||||
|
||||
use League\CommonMark\Parser\Block\BlockStart;
|
||||
use League\CommonMark\Parser\Block\BlockStartParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
use League\CommonMark\Parser\MarkdownParserStateInterface;
|
||||
|
||||
final class BlockQuoteStartParser implements BlockStartParserInterface
|
||||
{
|
||||
public function tryStart(Cursor $cursor, MarkdownParserStateInterface $parserState): ?BlockStart
|
||||
{
|
||||
if ($cursor->isIndented()) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
if ($cursor->getNextNonSpaceCharacter() !== '>') {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
$cursor->advanceBy(1);
|
||||
$cursor->advanceBySpaceOrTab();
|
||||
|
||||
return BlockStart::of(new BlockQuoteParser())->at($cursor);
|
||||
}
|
||||
}
|
||||
84
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/FencedCodeParser.php
vendored
Normal file
84
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/FencedCodeParser.php
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
<?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\Extension\CommonMark\Parser\Block;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\FencedCode;
|
||||
use League\CommonMark\Parser\Block\AbstractBlockContinueParser;
|
||||
use League\CommonMark\Parser\Block\BlockContinue;
|
||||
use League\CommonMark\Parser\Block\BlockContinueParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
use League\CommonMark\Util\ArrayCollection;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
final class FencedCodeParser extends AbstractBlockContinueParser
|
||||
{
|
||||
/** @psalm-readonly */
|
||||
private FencedCode $block;
|
||||
|
||||
/** @var ArrayCollection<string> */
|
||||
private ArrayCollection $strings;
|
||||
|
||||
public function __construct(int $fenceLength, string $fenceChar, int $fenceOffset)
|
||||
{
|
||||
$this->block = new FencedCode($fenceLength, $fenceChar, $fenceOffset);
|
||||
$this->strings = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getBlock(): FencedCode
|
||||
{
|
||||
return $this->block;
|
||||
}
|
||||
|
||||
public function tryContinue(Cursor $cursor, BlockContinueParserInterface $activeBlockParser): ?BlockContinue
|
||||
{
|
||||
// Check for closing code fence
|
||||
if (! $cursor->isIndented() && $cursor->getNextNonSpaceCharacter() === $this->block->getChar()) {
|
||||
$match = RegexHelper::matchFirst('/^(?:`{3,}|~{3,})(?= *$)/', $cursor->getLine(), $cursor->getNextNonSpacePosition());
|
||||
if ($match !== null && \strlen($match[0]) >= $this->block->getLength()) {
|
||||
// closing fence - we're at end of line, so we can finalize now
|
||||
return BlockContinue::finished();
|
||||
}
|
||||
}
|
||||
|
||||
// Skip optional spaces of fence offset
|
||||
// Optimization: don't attempt to match if we're at a non-space position
|
||||
if ($cursor->getNextNonSpacePosition() > $cursor->getPosition()) {
|
||||
$cursor->match('/^ {0,' . $this->block->getOffset() . '}/');
|
||||
}
|
||||
|
||||
return BlockContinue::at($cursor);
|
||||
}
|
||||
|
||||
public function addLine(string $line): void
|
||||
{
|
||||
$this->strings[] = $line;
|
||||
}
|
||||
|
||||
public function closeBlock(): void
|
||||
{
|
||||
// first line becomes info string
|
||||
$firstLine = $this->strings->first();
|
||||
if ($firstLine === false) {
|
||||
$firstLine = '';
|
||||
}
|
||||
|
||||
$this->block->setInfo(RegexHelper::unescape(\trim($firstLine)));
|
||||
|
||||
if ($this->strings->count() === 1) {
|
||||
$this->block->setLiteral('');
|
||||
} else {
|
||||
$this->block->setLiteral(\implode("\n", $this->strings->slice(1)) . "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
40
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/FencedCodeStartParser.php
vendored
Normal file
40
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/FencedCodeStartParser.php
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
<?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\Extension\CommonMark\Parser\Block;
|
||||
|
||||
use League\CommonMark\Parser\Block\BlockStart;
|
||||
use League\CommonMark\Parser\Block\BlockStartParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
use League\CommonMark\Parser\MarkdownParserStateInterface;
|
||||
|
||||
final class FencedCodeStartParser implements BlockStartParserInterface
|
||||
{
|
||||
public function tryStart(Cursor $cursor, MarkdownParserStateInterface $parserState): ?BlockStart
|
||||
{
|
||||
if ($cursor->isIndented() || ! \in_array($cursor->getNextNonSpaceCharacter(), ['`', '~'], true)) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
$indent = $cursor->getIndent();
|
||||
$fence = $cursor->match('/^[ \t]*(?:`{3,}(?!.*`)|~{3,})/');
|
||||
if ($fence === null) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
// fenced code block
|
||||
$fence = \ltrim($fence, " \t");
|
||||
|
||||
return BlockStart::of(new FencedCodeParser(\strlen($fence), $fence[0], $indent))->at($cursor);
|
||||
}
|
||||
}
|
||||
51
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/HeadingParser.php
vendored
Normal file
51
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/HeadingParser.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?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\Extension\CommonMark\Parser\Block;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\Heading;
|
||||
use League\CommonMark\Parser\Block\AbstractBlockContinueParser;
|
||||
use League\CommonMark\Parser\Block\BlockContinue;
|
||||
use League\CommonMark\Parser\Block\BlockContinueParserInterface;
|
||||
use League\CommonMark\Parser\Block\BlockContinueParserWithInlinesInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
use League\CommonMark\Parser\InlineParserEngineInterface;
|
||||
|
||||
final class HeadingParser extends AbstractBlockContinueParser implements BlockContinueParserWithInlinesInterface
|
||||
{
|
||||
/** @psalm-readonly */
|
||||
private Heading $block;
|
||||
|
||||
private string $content;
|
||||
|
||||
public function __construct(int $level, string $content)
|
||||
{
|
||||
$this->block = new Heading($level);
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
public function getBlock(): Heading
|
||||
{
|
||||
return $this->block;
|
||||
}
|
||||
|
||||
public function tryContinue(Cursor $cursor, BlockContinueParserInterface $activeBlockParser): ?BlockContinue
|
||||
{
|
||||
return BlockContinue::none();
|
||||
}
|
||||
|
||||
public function parseInlines(InlineParserEngineInterface $inlineParser): void
|
||||
{
|
||||
$inlineParser->parse($this->content, $this->block);
|
||||
}
|
||||
}
|
||||
80
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/HeadingStartParser.php
vendored
Normal file
80
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/HeadingStartParser.php
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
<?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\Extension\CommonMark\Parser\Block;
|
||||
|
||||
use League\CommonMark\Parser\Block\BlockStart;
|
||||
use League\CommonMark\Parser\Block\BlockStartParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
use League\CommonMark\Parser\MarkdownParserStateInterface;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
class HeadingStartParser implements BlockStartParserInterface
|
||||
{
|
||||
public function tryStart(Cursor $cursor, MarkdownParserStateInterface $parserState): ?BlockStart
|
||||
{
|
||||
if ($cursor->isIndented() || ! \in_array($cursor->getNextNonSpaceCharacter(), ['#', '-', '='], true)) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
|
||||
if ($atxHeading = self::getAtxHeader($cursor)) {
|
||||
return BlockStart::of($atxHeading)->at($cursor);
|
||||
}
|
||||
|
||||
$setextHeadingLevel = self::getSetextHeadingLevel($cursor);
|
||||
if ($setextHeadingLevel > 0) {
|
||||
$content = $parserState->getParagraphContent();
|
||||
if ($content !== null) {
|
||||
$cursor->advanceToEnd();
|
||||
|
||||
return BlockStart::of(new HeadingParser($setextHeadingLevel, $content))
|
||||
->at($cursor)
|
||||
->replaceActiveBlockParser();
|
||||
}
|
||||
}
|
||||
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
private static function getAtxHeader(Cursor $cursor): ?HeadingParser
|
||||
{
|
||||
$match = RegexHelper::matchFirst('/^#{1,6}(?:[ \t]+|$)/', $cursor->getRemainder());
|
||||
if (! $match) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
$cursor->advanceBy(\strlen($match[0]));
|
||||
|
||||
$level = \strlen(\trim($match[0]));
|
||||
$str = $cursor->getRemainder();
|
||||
$str = \preg_replace('/^[ \t]*#+[ \t]*$/', '', $str);
|
||||
\assert(\is_string($str));
|
||||
$str = \preg_replace('/[ \t]+#+[ \t]*$/', '', $str);
|
||||
\assert(\is_string($str));
|
||||
|
||||
return new HeadingParser($level, $str);
|
||||
}
|
||||
|
||||
private static function getSetextHeadingLevel(Cursor $cursor): int
|
||||
{
|
||||
$match = RegexHelper::matchFirst('/^(?:=+|-+)[ \t]*$/', $cursor->getRemainder());
|
||||
if ($match === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $match[0][0] === '=' ? 1 : 2;
|
||||
}
|
||||
}
|
||||
82
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/HtmlBlockParser.php
vendored
Normal file
82
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/HtmlBlockParser.php
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
<?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\Extension\CommonMark\Parser\Block;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\HtmlBlock;
|
||||
use League\CommonMark\Parser\Block\AbstractBlockContinueParser;
|
||||
use League\CommonMark\Parser\Block\BlockContinue;
|
||||
use League\CommonMark\Parser\Block\BlockContinueParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
final class HtmlBlockParser extends AbstractBlockContinueParser
|
||||
{
|
||||
/** @psalm-readonly */
|
||||
private HtmlBlock $block;
|
||||
|
||||
private string $content = '';
|
||||
|
||||
private bool $finished = false;
|
||||
|
||||
/**
|
||||
* @psalm-param HtmlBlock::TYPE_* $blockType
|
||||
*
|
||||
* @phpstan-param HtmlBlock::TYPE_* $blockType
|
||||
*/
|
||||
public function __construct(int $blockType)
|
||||
{
|
||||
$this->block = new HtmlBlock($blockType);
|
||||
}
|
||||
|
||||
public function getBlock(): HtmlBlock
|
||||
{
|
||||
return $this->block;
|
||||
}
|
||||
|
||||
public function tryContinue(Cursor $cursor, BlockContinueParserInterface $activeBlockParser): ?BlockContinue
|
||||
{
|
||||
if ($this->finished) {
|
||||
return BlockContinue::none();
|
||||
}
|
||||
|
||||
if ($cursor->isBlank() && \in_array($this->block->getType(), [HtmlBlock::TYPE_6_BLOCK_ELEMENT, HtmlBlock::TYPE_7_MISC_ELEMENT], true)) {
|
||||
return BlockContinue::none();
|
||||
}
|
||||
|
||||
return BlockContinue::at($cursor);
|
||||
}
|
||||
|
||||
public function addLine(string $line): void
|
||||
{
|
||||
if ($this->content !== '') {
|
||||
$this->content .= "\n";
|
||||
}
|
||||
|
||||
$this->content .= $line;
|
||||
|
||||
// Check for end condition
|
||||
// phpcs:disable SlevomatCodingStandard.ControlStructures.EarlyExit.EarlyExitNotUsed
|
||||
if ($this->block->getType() <= HtmlBlock::TYPE_5_CDATA) {
|
||||
if (\preg_match(RegexHelper::getHtmlBlockCloseRegex($this->block->getType()), $line) === 1) {
|
||||
$this->finished = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function closeBlock(): void
|
||||
{
|
||||
$this->block->setLiteral($this->content);
|
||||
$this->content = '';
|
||||
}
|
||||
}
|
||||
62
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/HtmlBlockStartParser.php
vendored
Normal file
62
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/HtmlBlockStartParser.php
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
<?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\Extension\CommonMark\Parser\Block;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\HtmlBlock;
|
||||
use League\CommonMark\Node\Block\Paragraph;
|
||||
use League\CommonMark\Parser\Block\BlockStart;
|
||||
use League\CommonMark\Parser\Block\BlockStartParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
use League\CommonMark\Parser\MarkdownParserStateInterface;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
final class HtmlBlockStartParser implements BlockStartParserInterface
|
||||
{
|
||||
public function tryStart(Cursor $cursor, MarkdownParserStateInterface $parserState): ?BlockStart
|
||||
{
|
||||
if ($cursor->isIndented() || $cursor->getNextNonSpaceCharacter() !== '<') {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
$tmpCursor = clone $cursor;
|
||||
$tmpCursor->advanceToNextNonSpaceOrTab();
|
||||
$line = $tmpCursor->getRemainder();
|
||||
|
||||
for ($blockType = 1; $blockType <= 7; $blockType++) {
|
||||
/** @psalm-var HtmlBlock::TYPE_* $blockType */
|
||||
/** @phpstan-var HtmlBlock::TYPE_* $blockType */
|
||||
$match = RegexHelper::matchAt(
|
||||
RegexHelper::getHtmlBlockOpenRegex($blockType),
|
||||
$line
|
||||
);
|
||||
|
||||
if ($match !== null && ($blockType < 7 || $this->isType7BlockAllowed($cursor, $parserState))) {
|
||||
return BlockStart::of(new HtmlBlockParser($blockType))->at($cursor);
|
||||
}
|
||||
}
|
||||
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
private function isType7BlockAllowed(Cursor $cursor, MarkdownParserStateInterface $parserState): bool
|
||||
{
|
||||
// Type 7 blocks can't interrupt paragraphs
|
||||
if ($parserState->getLastMatchedBlockParser()->getBlock() instanceof Paragraph) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Even lazy ones
|
||||
return ! $parserState->getActiveBlockParser()->canHaveLazyContinuationLines();
|
||||
}
|
||||
}
|
||||
83
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/IndentedCodeParser.php
vendored
Normal file
83
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/IndentedCodeParser.php
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
<?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\Extension\CommonMark\Parser\Block;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\IndentedCode;
|
||||
use League\CommonMark\Parser\Block\AbstractBlockContinueParser;
|
||||
use League\CommonMark\Parser\Block\BlockContinue;
|
||||
use League\CommonMark\Parser\Block\BlockContinueParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
use League\CommonMark\Util\ArrayCollection;
|
||||
|
||||
final class IndentedCodeParser extends AbstractBlockContinueParser
|
||||
{
|
||||
/** @psalm-readonly */
|
||||
private IndentedCode $block;
|
||||
|
||||
/** @var ArrayCollection<string> */
|
||||
private ArrayCollection $strings;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->block = new IndentedCode();
|
||||
$this->strings = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getBlock(): IndentedCode
|
||||
{
|
||||
return $this->block;
|
||||
}
|
||||
|
||||
public function tryContinue(Cursor $cursor, BlockContinueParserInterface $activeBlockParser): ?BlockContinue
|
||||
{
|
||||
if ($cursor->isIndented()) {
|
||||
$cursor->advanceBy(Cursor::INDENT_LEVEL, true);
|
||||
|
||||
return BlockContinue::at($cursor);
|
||||
}
|
||||
|
||||
if ($cursor->isBlank()) {
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
|
||||
return BlockContinue::at($cursor);
|
||||
}
|
||||
|
||||
return BlockContinue::none();
|
||||
}
|
||||
|
||||
public function addLine(string $line): void
|
||||
{
|
||||
$this->strings[] = $line;
|
||||
}
|
||||
|
||||
public function closeBlock(): void
|
||||
{
|
||||
$reversed = \array_reverse($this->strings->toArray(), true);
|
||||
foreach ($reversed as $index => $line) {
|
||||
if ($line !== '' && $line !== "\n" && ! \preg_match('/^(\n *)$/', $line)) {
|
||||
break;
|
||||
}
|
||||
|
||||
unset($reversed[$index]);
|
||||
}
|
||||
|
||||
$fixed = \array_reverse($reversed);
|
||||
$tmp = \implode("\n", $fixed);
|
||||
if (\substr($tmp, -1) !== "\n") {
|
||||
$tmp .= "\n";
|
||||
}
|
||||
|
||||
$this->block->setLiteral($tmp);
|
||||
}
|
||||
}
|
||||
42
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/IndentedCodeStartParser.php
vendored
Normal file
42
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/IndentedCodeStartParser.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?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\Extension\CommonMark\Parser\Block;
|
||||
|
||||
use League\CommonMark\Node\Block\Paragraph;
|
||||
use League\CommonMark\Parser\Block\BlockStart;
|
||||
use League\CommonMark\Parser\Block\BlockStartParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
use League\CommonMark\Parser\MarkdownParserStateInterface;
|
||||
|
||||
final class IndentedCodeStartParser implements BlockStartParserInterface
|
||||
{
|
||||
public function tryStart(Cursor $cursor, MarkdownParserStateInterface $parserState): ?BlockStart
|
||||
{
|
||||
if (! $cursor->isIndented()) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
if ($parserState->getActiveBlockParser()->getBlock() instanceof Paragraph) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
if ($cursor->isBlank()) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
$cursor->advanceBy(Cursor::INDENT_LEVEL, true);
|
||||
|
||||
return BlockStart::of(new IndentedCodeParser())->at($cursor);
|
||||
}
|
||||
}
|
||||
79
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/ListBlockParser.php
vendored
Normal file
79
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/ListBlockParser.php
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
<?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\Extension\CommonMark\Parser\Block;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\ListBlock;
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\ListData;
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\ListItem;
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
use League\CommonMark\Parser\Block\AbstractBlockContinueParser;
|
||||
use League\CommonMark\Parser\Block\BlockContinue;
|
||||
use League\CommonMark\Parser\Block\BlockContinueParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
|
||||
final class ListBlockParser extends AbstractBlockContinueParser
|
||||
{
|
||||
/** @psalm-readonly */
|
||||
private ListBlock $block;
|
||||
|
||||
private bool $hadBlankLine = false;
|
||||
|
||||
private int $linesAfterBlank = 0;
|
||||
|
||||
public function __construct(ListData $listData)
|
||||
{
|
||||
$this->block = new ListBlock($listData);
|
||||
}
|
||||
|
||||
public function getBlock(): ListBlock
|
||||
{
|
||||
return $this->block;
|
||||
}
|
||||
|
||||
public function isContainer(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canContain(AbstractBlock $childBlock): bool
|
||||
{
|
||||
if (! $childBlock instanceof ListItem) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Another list item is being added to this list block.
|
||||
// If the previous line was blank, that means this list
|
||||
// block is "loose" (not tight).
|
||||
if ($this->hadBlankLine && $this->linesAfterBlank === 1) {
|
||||
$this->block->setTight(false);
|
||||
$this->hadBlankLine = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function tryContinue(Cursor $cursor, BlockContinueParserInterface $activeBlockParser): ?BlockContinue
|
||||
{
|
||||
if ($cursor->isBlank()) {
|
||||
$this->hadBlankLine = true;
|
||||
$this->linesAfterBlank = 0;
|
||||
} elseif ($this->hadBlankLine) {
|
||||
$this->linesAfterBlank++;
|
||||
}
|
||||
|
||||
// List blocks themselves don't have any markers, only list items. So try to stay in the list.
|
||||
// If there is a block start other than list item, canContain makes sure that this list is closed.
|
||||
return BlockContinue::at($cursor);
|
||||
}
|
||||
}
|
||||
146
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/ListBlockStartParser.php
vendored
Normal file
146
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/ListBlockStartParser.php
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
<?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\Extension\CommonMark\Parser\Block;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\ListBlock;
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\ListData;
|
||||
use League\CommonMark\Parser\Block\BlockStart;
|
||||
use League\CommonMark\Parser\Block\BlockStartParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
use League\CommonMark\Parser\MarkdownParserStateInterface;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
use League\Config\ConfigurationAwareInterface;
|
||||
use League\Config\ConfigurationInterface;
|
||||
|
||||
final class ListBlockStartParser implements BlockStartParserInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @psalm-readonly-allow-private-mutation */
|
||||
private ?ConfigurationInterface $config = null;
|
||||
|
||||
/** @psalm-readonly-allow-private-mutation */
|
||||
private ?string $listMarkerRegex = null;
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration): void
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
|
||||
public function tryStart(Cursor $cursor, MarkdownParserStateInterface $parserState): ?BlockStart
|
||||
{
|
||||
if ($cursor->isIndented()) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
$listData = $this->parseList($cursor, $parserState->getParagraphContent() !== null);
|
||||
if ($listData === null) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
$listItemParser = new ListItemParser($listData);
|
||||
|
||||
// prepend the list block if needed
|
||||
$matched = $parserState->getLastMatchedBlockParser();
|
||||
if (! ($matched instanceof ListBlockParser) || ! $listData->equals($matched->getBlock()->getListData())) {
|
||||
$listBlockParser = new ListBlockParser($listData);
|
||||
// We start out with assuming a list is tight. If we find a blank line, we set it to loose later.
|
||||
$listBlockParser->getBlock()->setTight(true);
|
||||
|
||||
return BlockStart::of($listBlockParser, $listItemParser)->at($cursor);
|
||||
}
|
||||
|
||||
return BlockStart::of($listItemParser)->at($cursor);
|
||||
}
|
||||
|
||||
private function parseList(Cursor $cursor, bool $inParagraph): ?ListData
|
||||
{
|
||||
$indent = $cursor->getIndent();
|
||||
|
||||
$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)) && (! $inParagraph || $matches[1] === '1')) {
|
||||
$data = new ListData();
|
||||
$data->markerOffset = $indent;
|
||||
$data->type = ListBlock::TYPE_ORDERED;
|
||||
$data->start = (int) $matches[1];
|
||||
$data->delimiter = $matches[2] === '.' ? ListBlock::DELIM_PERIOD : ListBlock::DELIM_PAREN;
|
||||
$data->bulletChar = null;
|
||||
$markerLength = \strlen($matches[0]);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Make sure we have spaces after
|
||||
$nextChar = $tmpCursor->peek($markerLength);
|
||||
if (! ($nextChar === null || $nextChar === "\t" || $nextChar === ' ')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// If it interrupts paragraph, make sure first line isn't blank
|
||||
if ($inParagraph && ! RegexHelper::matchAt(RegexHelper::REGEX_NON_SPACE, $rest, $markerLength)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$cursor->advanceToNextNonSpaceOrTab(); // to start of marker
|
||||
$cursor->advanceBy($markerLength, true); // to end of marker
|
||||
$data->padding = self::calculateListMarkerPadding($cursor, $markerLength);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private static 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 = '/^[*+-]/';
|
||||
}
|
||||
|
||||
$markers = $this->config->get('commonmark/unordered_list_markers');
|
||||
\assert(\is_array($markers));
|
||||
|
||||
return $this->listMarkerRegex = '/^[' . \preg_quote(\implode('', $markers), '/') . ']/';
|
||||
}
|
||||
}
|
||||
90
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/ListItemParser.php
vendored
Normal file
90
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/ListItemParser.php
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
<?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\Extension\CommonMark\Parser\Block;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\ListBlock;
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\ListData;
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\ListItem;
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
use League\CommonMark\Node\Block\Paragraph;
|
||||
use League\CommonMark\Parser\Block\AbstractBlockContinueParser;
|
||||
use League\CommonMark\Parser\Block\BlockContinue;
|
||||
use League\CommonMark\Parser\Block\BlockContinueParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
|
||||
final class ListItemParser extends AbstractBlockContinueParser
|
||||
{
|
||||
/** @psalm-readonly */
|
||||
private ListItem $block;
|
||||
|
||||
private bool $hadBlankLine = false;
|
||||
|
||||
public function __construct(ListData $listData)
|
||||
{
|
||||
$this->block = new ListItem($listData);
|
||||
}
|
||||
|
||||
public function getBlock(): ListItem
|
||||
{
|
||||
return $this->block;
|
||||
}
|
||||
|
||||
public function isContainer(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canContain(AbstractBlock $childBlock): bool
|
||||
{
|
||||
if ($this->hadBlankLine) {
|
||||
// We saw a blank line in this list item, that means the list block is loose.
|
||||
//
|
||||
// spec: if any of its constituent list items directly contain two block-level elements with a blank line
|
||||
// between them
|
||||
$parent = $this->block->parent();
|
||||
if ($parent instanceof ListBlock) {
|
||||
$parent->setTight(false);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function tryContinue(Cursor $cursor, BlockContinueParserInterface $activeBlockParser): ?BlockContinue
|
||||
{
|
||||
if ($cursor->isBlank()) {
|
||||
if ($this->block->firstChild() === null) {
|
||||
// Blank line after empty list item
|
||||
return BlockContinue::none();
|
||||
}
|
||||
|
||||
$activeBlock = $activeBlockParser->getBlock();
|
||||
// If the active block is a code block, blank lines in it should not affect if the list is tight.
|
||||
$this->hadBlankLine = $activeBlock instanceof Paragraph || $activeBlock instanceof ListItem;
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
|
||||
return BlockContinue::at($cursor);
|
||||
}
|
||||
|
||||
$contentIndent = $this->block->getListData()->markerOffset + $this->getBlock()->getListData()->padding;
|
||||
if ($cursor->getIndent() >= $contentIndent) {
|
||||
$cursor->advanceBy($contentIndent, true);
|
||||
|
||||
return BlockContinue::at($cursor);
|
||||
}
|
||||
|
||||
// Note: We'll hit this case for lazy continuation lines, they will get added later.
|
||||
return BlockContinue::none();
|
||||
}
|
||||
}
|
||||
42
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/ThematicBreakParser.php
vendored
Normal file
42
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/ThematicBreakParser.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?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\Extension\CommonMark\Parser\Block;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\ThematicBreak;
|
||||
use League\CommonMark\Parser\Block\AbstractBlockContinueParser;
|
||||
use League\CommonMark\Parser\Block\BlockContinue;
|
||||
use League\CommonMark\Parser\Block\BlockContinueParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
|
||||
final class ThematicBreakParser extends AbstractBlockContinueParser
|
||||
{
|
||||
/** @psalm-readonly */
|
||||
private ThematicBreak $block;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->block = new ThematicBreak();
|
||||
}
|
||||
|
||||
public function getBlock(): ThematicBreak
|
||||
{
|
||||
return $this->block;
|
||||
}
|
||||
|
||||
public function tryContinue(Cursor $cursor, BlockContinueParserInterface $activeBlockParser): ?BlockContinue
|
||||
{
|
||||
// a horizontal rule can never container > 1 line, so fail to match
|
||||
return BlockContinue::none();
|
||||
}
|
||||
}
|
||||
40
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/ThematicBreakStartParser.php
vendored
Normal file
40
vendor/league/commonmark/src/Extension/CommonMark/Parser/Block/ThematicBreakStartParser.php
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
<?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\Extension\CommonMark\Parser\Block;
|
||||
|
||||
use League\CommonMark\Parser\Block\BlockStart;
|
||||
use League\CommonMark\Parser\Block\BlockStartParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
use League\CommonMark\Parser\MarkdownParserStateInterface;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
final class ThematicBreakStartParser implements BlockStartParserInterface
|
||||
{
|
||||
public function tryStart(Cursor $cursor, MarkdownParserStateInterface $parserState): ?BlockStart
|
||||
{
|
||||
if ($cursor->isIndented()) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
$match = RegexHelper::matchAt(RegexHelper::REGEX_THEMATIC_BREAK, $cursor->getLine(), $cursor->getNextNonSpacePosition());
|
||||
if ($match === null) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
// Advance to the end of the string, consuming the entire line (of the thematic break)
|
||||
$cursor->advanceToEnd();
|
||||
|
||||
return BlockStart::of(new ThematicBreakParser())->at($cursor);
|
||||
}
|
||||
}
|
||||
54
vendor/league/commonmark/src/Extension/CommonMark/Parser/Inline/AutolinkParser.php
vendored
Normal file
54
vendor/league/commonmark/src/Extension/CommonMark/Parser/Inline/AutolinkParser.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Parser\Inline;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\Link;
|
||||
use League\CommonMark\Parser\Inline\InlineParserInterface;
|
||||
use League\CommonMark\Parser\Inline\InlineParserMatch;
|
||||
use League\CommonMark\Parser\InlineParserContext;
|
||||
use League\CommonMark\Util\UrlEncoder;
|
||||
|
||||
final class AutolinkParser implements InlineParserInterface
|
||||
{
|
||||
private const EMAIL_REGEX = '<([a-zA-Z0-9.!#$%&\'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)>';
|
||||
private const OTHER_LINK_REGEX = '<([A-Za-z][A-Za-z0-9.+-]{1,31}:[^<>\x00-\x20]*)>';
|
||||
|
||||
public function getMatchDefinition(): InlineParserMatch
|
||||
{
|
||||
return InlineParserMatch::regex(self::EMAIL_REGEX . '|' . self::OTHER_LINK_REGEX);
|
||||
}
|
||||
|
||||
public function parse(InlineParserContext $inlineContext): bool
|
||||
{
|
||||
$inlineContext->getCursor()->advanceBy($inlineContext->getFullMatchLength());
|
||||
$matches = $inlineContext->getMatches();
|
||||
|
||||
if ($matches[1] !== '') {
|
||||
$inlineContext->getContainer()->appendChild(new Link('mailto:' . UrlEncoder::unescapeAndEncode($matches[1]), $matches[1]));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($matches[2] !== '') {
|
||||
$inlineContext->getContainer()->appendChild(new Link(UrlEncoder::unescapeAndEncode($matches[2]), $matches[2]));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; // This should never happen
|
||||
}
|
||||
}
|
||||
70
vendor/league/commonmark/src/Extension/CommonMark/Parser/Inline/BacktickParser.php
vendored
Normal file
70
vendor/league/commonmark/src/Extension/CommonMark/Parser/Inline/BacktickParser.php
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Parser\Inline;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\Code;
|
||||
use League\CommonMark\Node\Inline\Text;
|
||||
use League\CommonMark\Parser\Inline\InlineParserInterface;
|
||||
use League\CommonMark\Parser\Inline\InlineParserMatch;
|
||||
use League\CommonMark\Parser\InlineParserContext;
|
||||
|
||||
final class BacktickParser implements InlineParserInterface
|
||||
{
|
||||
public function getMatchDefinition(): InlineParserMatch
|
||||
{
|
||||
return InlineParserMatch::regex('`+');
|
||||
}
|
||||
|
||||
public function parse(InlineParserContext $inlineContext): bool
|
||||
{
|
||||
$ticks = $inlineContext->getFullMatch();
|
||||
$cursor = $inlineContext->getCursor();
|
||||
$cursor->advanceBy($inlineContext->getFullMatchLength());
|
||||
|
||||
$currentPosition = $cursor->getPosition();
|
||||
$previousState = $cursor->saveState();
|
||||
|
||||
while ($matchingTicks = $cursor->match('/`+/m')) {
|
||||
if ($matchingTicks !== $ticks) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$code = $cursor->getSubstring($currentPosition, $cursor->getPosition() - $currentPosition - \strlen($ticks));
|
||||
|
||||
$c = \preg_replace('/\n/m', ' ', $code) ?? '';
|
||||
|
||||
if (
|
||||
$c !== '' &&
|
||||
$c[0] === ' ' &&
|
||||
\substr($c, -1, 1) === ' ' &&
|
||||
\preg_match('/[^ ]/', $c)
|
||||
) {
|
||||
$c = \substr($c, 1, -1);
|
||||
}
|
||||
|
||||
$inlineContext->getContainer()->appendChild(new Code($c));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we got here, we didn't match a closing backtick sequence
|
||||
$cursor->restoreState($previousState);
|
||||
$inlineContext->getContainer()->appendChild(new Text($ticks));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
46
vendor/league/commonmark/src/Extension/CommonMark/Parser/Inline/BangParser.php
vendored
Normal file
46
vendor/league/commonmark/src/Extension/CommonMark/Parser/Inline/BangParser.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Parser\Inline;
|
||||
|
||||
use League\CommonMark\Delimiter\Delimiter;
|
||||
use League\CommonMark\Node\Inline\Text;
|
||||
use League\CommonMark\Parser\Inline\InlineParserInterface;
|
||||
use League\CommonMark\Parser\Inline\InlineParserMatch;
|
||||
use League\CommonMark\Parser\InlineParserContext;
|
||||
|
||||
final class BangParser implements InlineParserInterface
|
||||
{
|
||||
public function getMatchDefinition(): InlineParserMatch
|
||||
{
|
||||
return InlineParserMatch::string('![');
|
||||
}
|
||||
|
||||
public function parse(InlineParserContext $inlineContext): bool
|
||||
{
|
||||
$cursor = $inlineContext->getCursor();
|
||||
$cursor->advanceBy(2);
|
||||
|
||||
$node = new Text('![', ['delim' => true]);
|
||||
$inlineContext->getContainer()->appendChild($node);
|
||||
|
||||
// Add entry to stack for this opener
|
||||
$delimiter = new Delimiter('!', 1, $node, true, false, $cursor->getPosition());
|
||||
$inlineContext->getDelimiterStack()->push($delimiter);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
212
vendor/league/commonmark/src/Extension/CommonMark/Parser/Inline/CloseBracketParser.php
vendored
Normal file
212
vendor/league/commonmark/src/Extension/CommonMark/Parser/Inline/CloseBracketParser.php
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Parser\Inline;
|
||||
|
||||
use League\CommonMark\Environment\EnvironmentAwareInterface;
|
||||
use League\CommonMark\Environment\EnvironmentInterface;
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\AbstractWebResource;
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\Image;
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\Link;
|
||||
use League\CommonMark\Extension\Mention\Mention;
|
||||
use League\CommonMark\Node\Inline\AdjacentTextMerger;
|
||||
use League\CommonMark\Node\Inline\Text;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
use League\CommonMark\Parser\Inline\InlineParserInterface;
|
||||
use League\CommonMark\Parser\Inline\InlineParserMatch;
|
||||
use League\CommonMark\Parser\InlineParserContext;
|
||||
use League\CommonMark\Reference\ReferenceInterface;
|
||||
use League\CommonMark\Reference\ReferenceMapInterface;
|
||||
use League\CommonMark\Util\LinkParserHelper;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
final class CloseBracketParser implements InlineParserInterface, EnvironmentAwareInterface
|
||||
{
|
||||
/** @psalm-readonly-allow-private-mutation */
|
||||
private EnvironmentInterface $environment;
|
||||
|
||||
public function getMatchDefinition(): InlineParserMatch
|
||||
{
|
||||
return InlineParserMatch::string(']');
|
||||
}
|
||||
|
||||
public function parse(InlineParserContext $inlineContext): bool
|
||||
{
|
||||
// Look through stack of delimiters for a [ or !
|
||||
$opener = $inlineContext->getDelimiterStack()->searchByCharacter(['[', '!']);
|
||||
if ($opener === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $opener->isActive()) {
|
||||
// no matched opener; remove from emphasis stack
|
||||
$inlineContext->getDelimiterStack()->removeDelimiter($opener);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$cursor = $inlineContext->getCursor();
|
||||
|
||||
$startPos = $cursor->getPosition();
|
||||
$previousState = $cursor->saveState();
|
||||
|
||||
$cursor->advanceBy(1);
|
||||
|
||||
// Check to see if we have a link/image
|
||||
|
||||
// Inline link?
|
||||
if ($result = $this->tryParseInlineLinkAndTitle($cursor)) {
|
||||
$link = $result;
|
||||
} elseif ($link = $this->tryParseReference($cursor, $inlineContext->getReferenceMap(), $opener->getIndex(), $startPos)) {
|
||||
$reference = $link;
|
||||
$link = ['url' => $link->getDestination(), 'title' => $link->getTitle()];
|
||||
} else {
|
||||
// No match
|
||||
$inlineContext->getDelimiterStack()->removeDelimiter($opener); // Remove this opener from stack
|
||||
$cursor->restoreState($previousState);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$isImage = $opener->getChar() === '!';
|
||||
|
||||
$inline = $this->createInline($link['url'], $link['title'], $isImage, $reference ?? null);
|
||||
$opener->getInlineNode()->replaceWith($inline);
|
||||
while (($label = $inline->next()) !== null) {
|
||||
// Is there a Mention or Link contained within this link?
|
||||
// CommonMark does not allow nested links, so we'll restore the original text.
|
||||
if ($label instanceof Mention) {
|
||||
$label->replaceWith($replacement = new Text($label->getPrefix() . $label->getIdentifier()));
|
||||
$inline->appendChild($replacement);
|
||||
} elseif ($label instanceof Link) {
|
||||
foreach ($label->children() as $child) {
|
||||
$label->insertBefore($child);
|
||||
}
|
||||
|
||||
$label->detach();
|
||||
} else {
|
||||
$inline->appendChild($label);
|
||||
}
|
||||
}
|
||||
|
||||
// Process delimiters such as emphasis inside link/image
|
||||
$delimiterStack = $inlineContext->getDelimiterStack();
|
||||
$stackBottom = $opener->getPrevious();
|
||||
$delimiterStack->processDelimiters($stackBottom, $this->environment->getDelimiterProcessors());
|
||||
$delimiterStack->removeAll($stackBottom);
|
||||
|
||||
// Merge any adjacent Text nodes together
|
||||
AdjacentTextMerger::mergeChildNodes($inline);
|
||||
|
||||
// processEmphasis will remove this and later delimiters.
|
||||
// Now, for a link, we also remove earlier link openers (no links in links)
|
||||
if (! $isImage) {
|
||||
$inlineContext->getDelimiterStack()->removeEarlierMatches('[');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function setEnvironment(EnvironmentInterface $environment): void
|
||||
{
|
||||
$this->environment = $environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>|null
|
||||
*/
|
||||
private function tryParseInlineLinkAndTitle(Cursor $cursor): ?array
|
||||
{
|
||||
if ($cursor->getCurrentCharacter() !== '(') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$previousState = $cursor->saveState();
|
||||
|
||||
$cursor->advanceBy(1);
|
||||
$cursor->advanceToNextNonSpaceOrNewline();
|
||||
if (($dest = LinkParserHelper::parseLinkDestination($cursor)) === null) {
|
||||
$cursor->restoreState($previousState);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$cursor->advanceToNextNonSpaceOrNewline();
|
||||
$previousCharacter = $cursor->peek(-1);
|
||||
// We know from previous lines that we've advanced at least one space so far, so this next call should never be null
|
||||
\assert(\is_string($previousCharacter));
|
||||
|
||||
$title = '';
|
||||
// make sure there's a space before the title:
|
||||
if (\preg_match(RegexHelper::REGEX_WHITESPACE_CHAR, $previousCharacter)) {
|
||||
$title = LinkParserHelper::parseLinkTitle($cursor) ?? '';
|
||||
}
|
||||
|
||||
$cursor->advanceToNextNonSpaceOrNewline();
|
||||
|
||||
if ($cursor->getCurrentCharacter() !== ')') {
|
||||
$cursor->restoreState($previousState);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$cursor->advanceBy(1);
|
||||
|
||||
return ['url' => $dest, 'title' => $title];
|
||||
}
|
||||
|
||||
private function tryParseReference(Cursor $cursor, ReferenceMapInterface $referenceMap, ?int $openerIndex, int $startPos): ?ReferenceInterface
|
||||
{
|
||||
if ($openerIndex === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$savePos = $cursor->saveState();
|
||||
$beforeLabel = $cursor->getPosition();
|
||||
$n = LinkParserHelper::parseLinkLabel($cursor);
|
||||
if ($n === 0 || $n === 2) {
|
||||
$start = $openerIndex;
|
||||
$length = $startPos - $openerIndex;
|
||||
} else {
|
||||
$start = $beforeLabel + 1;
|
||||
$length = $n - 2;
|
||||
}
|
||||
|
||||
$referenceLabel = $cursor->getSubstring($start, $length);
|
||||
|
||||
if ($n === 0) {
|
||||
// If shortcut reference link, rewind before spaces we skipped
|
||||
$cursor->restoreState($savePos);
|
||||
}
|
||||
|
||||
return $referenceMap->get($referenceLabel);
|
||||
}
|
||||
|
||||
private function createInline(string $url, string $title, bool $isImage, ?ReferenceInterface $reference = null): AbstractWebResource
|
||||
{
|
||||
if ($isImage) {
|
||||
$inline = new Image($url, null, $title);
|
||||
} else {
|
||||
$inline = new Link($url, null, $title);
|
||||
}
|
||||
|
||||
if ($reference) {
|
||||
$inline->data->set('reference', $reference);
|
||||
}
|
||||
|
||||
return $inline;
|
||||
}
|
||||
}
|
||||
42
vendor/league/commonmark/src/Extension/CommonMark/Parser/Inline/EntityParser.php
vendored
Normal file
42
vendor/league/commonmark/src/Extension/CommonMark/Parser/Inline/EntityParser.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Parser\Inline;
|
||||
|
||||
use League\CommonMark\Node\Inline\Text;
|
||||
use League\CommonMark\Parser\Inline\InlineParserInterface;
|
||||
use League\CommonMark\Parser\Inline\InlineParserMatch;
|
||||
use League\CommonMark\Parser\InlineParserContext;
|
||||
use League\CommonMark\Util\Html5EntityDecoder;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
final class EntityParser implements InlineParserInterface
|
||||
{
|
||||
public function getMatchDefinition(): InlineParserMatch
|
||||
{
|
||||
return InlineParserMatch::regex(RegexHelper::PARTIAL_ENTITY);
|
||||
}
|
||||
|
||||
public function parse(InlineParserContext $inlineContext): bool
|
||||
{
|
||||
$entity = $inlineContext->getFullMatch();
|
||||
|
||||
$inlineContext->getCursor()->advanceBy($inlineContext->getFullMatchLength());
|
||||
$inlineContext->getContainer()->appendChild(new Text(Html5EntityDecoder::decode($entity)));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
57
vendor/league/commonmark/src/Extension/CommonMark/Parser/Inline/EscapableParser.php
vendored
Normal file
57
vendor/league/commonmark/src/Extension/CommonMark/Parser/Inline/EscapableParser.php
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Parser\Inline;
|
||||
|
||||
use League\CommonMark\Node\Inline\Newline;
|
||||
use League\CommonMark\Node\Inline\Text;
|
||||
use League\CommonMark\Parser\Inline\InlineParserInterface;
|
||||
use League\CommonMark\Parser\Inline\InlineParserMatch;
|
||||
use League\CommonMark\Parser\InlineParserContext;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
final class EscapableParser implements InlineParserInterface
|
||||
{
|
||||
public function getMatchDefinition(): InlineParserMatch
|
||||
{
|
||||
return InlineParserMatch::string('\\');
|
||||
}
|
||||
|
||||
public function parse(InlineParserContext $inlineContext): bool
|
||||
{
|
||||
$cursor = $inlineContext->getCursor();
|
||||
$nextChar = $cursor->peek();
|
||||
|
||||
if ($nextChar === "\n") {
|
||||
$cursor->advanceBy(2);
|
||||
$inlineContext->getContainer()->appendChild(new Newline(Newline::HARDBREAK));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($nextChar !== null && RegexHelper::isEscapable($nextChar)) {
|
||||
$cursor->advanceBy(2);
|
||||
$inlineContext->getContainer()->appendChild(new Text($nextChar));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$cursor->advanceBy(1);
|
||||
$inlineContext->getContainer()->appendChild(new Text('\\'));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
41
vendor/league/commonmark/src/Extension/CommonMark/Parser/Inline/HtmlInlineParser.php
vendored
Normal file
41
vendor/league/commonmark/src/Extension/CommonMark/Parser/Inline/HtmlInlineParser.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Parser\Inline;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\HtmlInline;
|
||||
use League\CommonMark\Parser\Inline\InlineParserInterface;
|
||||
use League\CommonMark\Parser\Inline\InlineParserMatch;
|
||||
use League\CommonMark\Parser\InlineParserContext;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
final class HtmlInlineParser implements InlineParserInterface
|
||||
{
|
||||
public function getMatchDefinition(): InlineParserMatch
|
||||
{
|
||||
return InlineParserMatch::regex(RegexHelper::PARTIAL_HTMLTAG)->caseSensitive();
|
||||
}
|
||||
|
||||
public function parse(InlineParserContext $inlineContext): bool
|
||||
{
|
||||
$inline = $inlineContext->getFullMatch();
|
||||
|
||||
$inlineContext->getCursor()->advanceBy($inlineContext->getFullMatchLength());
|
||||
$inlineContext->getContainer()->appendChild(new HtmlInline($inline));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
44
vendor/league/commonmark/src/Extension/CommonMark/Parser/Inline/OpenBracketParser.php
vendored
Normal file
44
vendor/league/commonmark/src/Extension/CommonMark/Parser/Inline/OpenBracketParser.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Parser\Inline;
|
||||
|
||||
use League\CommonMark\Delimiter\Delimiter;
|
||||
use League\CommonMark\Node\Inline\Text;
|
||||
use League\CommonMark\Parser\Inline\InlineParserInterface;
|
||||
use League\CommonMark\Parser\Inline\InlineParserMatch;
|
||||
use League\CommonMark\Parser\InlineParserContext;
|
||||
|
||||
final class OpenBracketParser implements InlineParserInterface
|
||||
{
|
||||
public function getMatchDefinition(): InlineParserMatch
|
||||
{
|
||||
return InlineParserMatch::string('[');
|
||||
}
|
||||
|
||||
public function parse(InlineParserContext $inlineContext): bool
|
||||
{
|
||||
$inlineContext->getCursor()->advanceBy(1);
|
||||
$node = new Text('[', ['delim' => true]);
|
||||
$inlineContext->getContainer()->appendChild($node);
|
||||
|
||||
// Add entry to stack for this opener
|
||||
$delimiter = new Delimiter('[', 1, $node, true, false, $inlineContext->getCursor()->getPosition());
|
||||
$inlineContext->getDelimiterStack()->push($delimiter);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
70
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Block/BlockQuoteRenderer.php
vendored
Normal file
70
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Block/BlockQuoteRenderer.php
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Renderer\Block;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\BlockQuote;
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
use League\CommonMark\Util\HtmlElement;
|
||||
use League\CommonMark\Xml\XmlNodeRendererInterface;
|
||||
|
||||
final class BlockQuoteRenderer implements NodeRendererInterface, XmlNodeRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param BlockQuote $node
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer): \Stringable
|
||||
{
|
||||
BlockQuote::assertInstanceOf($node);
|
||||
|
||||
$attrs = $node->data->get('attributes');
|
||||
|
||||
$filling = $childRenderer->renderNodes($node->children());
|
||||
$innerSeparator = $childRenderer->getInnerSeparator();
|
||||
if ($filling === '') {
|
||||
return new HtmlElement('blockquote', $attrs, $innerSeparator);
|
||||
}
|
||||
|
||||
return new HtmlElement(
|
||||
'blockquote',
|
||||
$attrs,
|
||||
$innerSeparator . $filling . $innerSeparator
|
||||
);
|
||||
}
|
||||
|
||||
public function getXmlTagName(Node $node): string
|
||||
{
|
||||
return 'block_quote';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BlockQuote $node
|
||||
*
|
||||
* @return array<string, scalar>
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function getXmlAttributes(Node $node): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
76
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Block/FencedCodeRenderer.php
vendored
Normal file
76
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Block/FencedCodeRenderer.php
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Renderer\Block;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\FencedCode;
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
use League\CommonMark\Util\HtmlElement;
|
||||
use League\CommonMark\Util\Xml;
|
||||
use League\CommonMark\Xml\XmlNodeRendererInterface;
|
||||
|
||||
final class FencedCodeRenderer implements NodeRendererInterface, XmlNodeRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param FencedCode $node
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer): \Stringable
|
||||
{
|
||||
FencedCode::assertInstanceOf($node);
|
||||
|
||||
$attrs = $node->data->getData('attributes');
|
||||
|
||||
$infoWords = $node->getInfoWords();
|
||||
if (\count($infoWords) !== 0 && $infoWords[0] !== '') {
|
||||
$attrs->append('class', 'language-' . $infoWords[0]);
|
||||
}
|
||||
|
||||
return new HtmlElement(
|
||||
'pre',
|
||||
[],
|
||||
new HtmlElement('code', $attrs->export(), Xml::escape($node->getLiteral()))
|
||||
);
|
||||
}
|
||||
|
||||
public function getXmlTagName(Node $node): string
|
||||
{
|
||||
return 'code_block';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FencedCode $node
|
||||
*
|
||||
* @return array<string, scalar>
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function getXmlAttributes(Node $node): array
|
||||
{
|
||||
FencedCode::assertInstanceOf($node);
|
||||
|
||||
if (($info = $node->getInfo()) === null || $info === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
return ['info' => $info];
|
||||
}
|
||||
}
|
||||
64
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Block/HeadingRenderer.php
vendored
Normal file
64
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Block/HeadingRenderer.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Renderer\Block;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\Heading;
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
use League\CommonMark\Util\HtmlElement;
|
||||
use League\CommonMark\Xml\XmlNodeRendererInterface;
|
||||
|
||||
final class HeadingRenderer implements NodeRendererInterface, XmlNodeRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param Heading $node
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer): \Stringable
|
||||
{
|
||||
Heading::assertInstanceOf($node);
|
||||
|
||||
$tag = 'h' . $node->getLevel();
|
||||
|
||||
$attrs = $node->data->get('attributes');
|
||||
|
||||
return new HtmlElement($tag, $attrs, $childRenderer->renderNodes($node->children()));
|
||||
}
|
||||
|
||||
public function getXmlTagName(Node $node): string
|
||||
{
|
||||
return 'heading';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Heading $node
|
||||
*
|
||||
* @return array<string, scalar>
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function getXmlAttributes(Node $node): array
|
||||
{
|
||||
Heading::assertInstanceOf($node);
|
||||
|
||||
return ['level' => $node->getLevel()];
|
||||
}
|
||||
}
|
||||
66
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Block/HtmlBlockRenderer.php
vendored
Normal file
66
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Block/HtmlBlockRenderer.php
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Renderer\Block;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\HtmlBlock;
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
use League\CommonMark\Util\HtmlFilter;
|
||||
use League\CommonMark\Xml\XmlNodeRendererInterface;
|
||||
use League\Config\ConfigurationAwareInterface;
|
||||
use League\Config\ConfigurationInterface;
|
||||
|
||||
final class HtmlBlockRenderer implements NodeRendererInterface, XmlNodeRendererInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @psalm-readonly-allow-private-mutation */
|
||||
private ConfigurationInterface $config;
|
||||
|
||||
/**
|
||||
* @param HtmlBlock $node
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer): string
|
||||
{
|
||||
HtmlBlock::assertInstanceOf($node);
|
||||
|
||||
$htmlInput = $this->config->get('html_input');
|
||||
|
||||
return HtmlFilter::filter($node->getLiteral(), $htmlInput);
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration): void
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
|
||||
public function getXmlTagName(Node $node): string
|
||||
{
|
||||
return 'html_block';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getXmlAttributes(Node $node): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
61
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Block/IndentedCodeRenderer.php
vendored
Normal file
61
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Block/IndentedCodeRenderer.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Renderer\Block;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\IndentedCode;
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
use League\CommonMark\Util\HtmlElement;
|
||||
use League\CommonMark\Util\Xml;
|
||||
use League\CommonMark\Xml\XmlNodeRendererInterface;
|
||||
|
||||
final class IndentedCodeRenderer implements NodeRendererInterface, XmlNodeRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param IndentedCode $node
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer): \Stringable
|
||||
{
|
||||
IndentedCode::assertInstanceOf($node);
|
||||
|
||||
$attrs = $node->data->get('attributes');
|
||||
|
||||
return new HtmlElement(
|
||||
'pre',
|
||||
[],
|
||||
new HtmlElement('code', $attrs, Xml::escape($node->getLiteral()))
|
||||
);
|
||||
}
|
||||
|
||||
public function getXmlTagName(Node $node): string
|
||||
{
|
||||
return 'code_block';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, scalar>
|
||||
*/
|
||||
public function getXmlAttributes(Node $node): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
86
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Block/ListBlockRenderer.php
vendored
Normal file
86
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Block/ListBlockRenderer.php
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Renderer\Block;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\ListBlock;
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
use League\CommonMark\Util\HtmlElement;
|
||||
use League\CommonMark\Xml\XmlNodeRendererInterface;
|
||||
|
||||
final class ListBlockRenderer implements NodeRendererInterface, XmlNodeRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param ListBlock $node
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer): \Stringable
|
||||
{
|
||||
ListBlock::assertInstanceOf($node);
|
||||
|
||||
$listData = $node->getListData();
|
||||
|
||||
$tag = $listData->type === ListBlock::TYPE_BULLET ? 'ul' : 'ol';
|
||||
|
||||
$attrs = $node->data->get('attributes');
|
||||
|
||||
if ($listData->start !== null && $listData->start !== 1) {
|
||||
$attrs['start'] = (string) $listData->start;
|
||||
}
|
||||
|
||||
$innerSeparator = $childRenderer->getInnerSeparator();
|
||||
|
||||
return new HtmlElement($tag, $attrs, $innerSeparator . $childRenderer->renderNodes($node->children()) . $innerSeparator);
|
||||
}
|
||||
|
||||
public function getXmlTagName(Node $node): string
|
||||
{
|
||||
return 'list';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ListBlock $node
|
||||
*
|
||||
* @return array<string, scalar>
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function getXmlAttributes(Node $node): array
|
||||
{
|
||||
ListBlock::assertInstanceOf($node);
|
||||
|
||||
$data = $node->getListData();
|
||||
|
||||
if ($data->type === ListBlock::TYPE_BULLET) {
|
||||
return [
|
||||
'type' => $data->type,
|
||||
'tight' => $node->isTight() ? 'true' : 'false',
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'type' => $data->type,
|
||||
'start' => $data->start ?? 1,
|
||||
'tight' => $node->isTight(),
|
||||
'delimiter' => $data->delimiter ?? ListBlock::DELIM_PERIOD,
|
||||
];
|
||||
}
|
||||
}
|
||||
74
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Block/ListItemRenderer.php
vendored
Normal file
74
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Block/ListItemRenderer.php
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Renderer\Block;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\ListItem;
|
||||
use League\CommonMark\Extension\TaskList\TaskListItemMarker;
|
||||
use League\CommonMark\Node\Block\Paragraph;
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
use League\CommonMark\Util\HtmlElement;
|
||||
use League\CommonMark\Xml\XmlNodeRendererInterface;
|
||||
|
||||
final class ListItemRenderer implements NodeRendererInterface, XmlNodeRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param ListItem $node
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer): \Stringable
|
||||
{
|
||||
ListItem::assertInstanceOf($node);
|
||||
|
||||
$contents = $childRenderer->renderNodes($node->children());
|
||||
if (\substr($contents, 0, 1) === '<' && ! $this->startsTaskListItem($node)) {
|
||||
$contents = "\n" . $contents;
|
||||
}
|
||||
|
||||
if (\substr($contents, -1, 1) === '>') {
|
||||
$contents .= "\n";
|
||||
}
|
||||
|
||||
$attrs = $node->data->get('attributes');
|
||||
|
||||
return new HtmlElement('li', $attrs, $contents);
|
||||
}
|
||||
|
||||
public function getXmlTagName(Node $node): string
|
||||
{
|
||||
return 'item';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getXmlAttributes(Node $node): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
private function startsTaskListItem(ListItem $block): bool
|
||||
{
|
||||
$firstChild = $block->firstChild();
|
||||
|
||||
return $firstChild instanceof Paragraph && $firstChild->firstChild() instanceof TaskListItemMarker;
|
||||
}
|
||||
}
|
||||
56
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Block/ThematicBreakRenderer.php
vendored
Normal file
56
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Block/ThematicBreakRenderer.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Renderer\Block;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\ThematicBreak;
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
use League\CommonMark\Util\HtmlElement;
|
||||
use League\CommonMark\Xml\XmlNodeRendererInterface;
|
||||
|
||||
final class ThematicBreakRenderer implements NodeRendererInterface, XmlNodeRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param ThematicBreak $node
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer): \Stringable
|
||||
{
|
||||
ThematicBreak::assertInstanceOf($node);
|
||||
|
||||
$attrs = $node->data->get('attributes');
|
||||
|
||||
return new HtmlElement('hr', $attrs, '', true);
|
||||
}
|
||||
|
||||
public function getXmlTagName(Node $node): string
|
||||
{
|
||||
return 'thematic_break';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getXmlAttributes(Node $node): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
57
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Inline/CodeRenderer.php
vendored
Normal file
57
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Inline/CodeRenderer.php
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Renderer\Inline;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\Code;
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
use League\CommonMark\Util\HtmlElement;
|
||||
use League\CommonMark\Util\Xml;
|
||||
use League\CommonMark\Xml\XmlNodeRendererInterface;
|
||||
|
||||
final class CodeRenderer implements NodeRendererInterface, XmlNodeRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param Code $node
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer): \Stringable
|
||||
{
|
||||
Code::assertInstanceOf($node);
|
||||
|
||||
$attrs = $node->data->get('attributes');
|
||||
|
||||
return new HtmlElement('code', $attrs, Xml::escape($node->getLiteral()));
|
||||
}
|
||||
|
||||
public function getXmlTagName(Node $node): string
|
||||
{
|
||||
return 'code';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getXmlAttributes(Node $node): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
56
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Inline/EmphasisRenderer.php
vendored
Normal file
56
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Inline/EmphasisRenderer.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Renderer\Inline;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\Emphasis;
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
use League\CommonMark\Util\HtmlElement;
|
||||
use League\CommonMark\Xml\XmlNodeRendererInterface;
|
||||
|
||||
final class EmphasisRenderer implements NodeRendererInterface, XmlNodeRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param Emphasis $node
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer): \Stringable
|
||||
{
|
||||
Emphasis::assertInstanceOf($node);
|
||||
|
||||
$attrs = $node->data->get('attributes');
|
||||
|
||||
return new HtmlElement('em', $attrs, $childRenderer->renderNodes($node->children()));
|
||||
}
|
||||
|
||||
public function getXmlTagName(Node $node): string
|
||||
{
|
||||
return 'emph';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getXmlAttributes(Node $node): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
66
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Inline/HtmlInlineRenderer.php
vendored
Normal file
66
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Inline/HtmlInlineRenderer.php
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Renderer\Inline;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\HtmlInline;
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
use League\CommonMark\Util\HtmlFilter;
|
||||
use League\CommonMark\Xml\XmlNodeRendererInterface;
|
||||
use League\Config\ConfigurationAwareInterface;
|
||||
use League\Config\ConfigurationInterface;
|
||||
|
||||
final class HtmlInlineRenderer implements NodeRendererInterface, XmlNodeRendererInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @psalm-readonly-allow-private-mutation */
|
||||
private ConfigurationInterface $config;
|
||||
|
||||
/**
|
||||
* @param HtmlInline $node
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer): string
|
||||
{
|
||||
HtmlInline::assertInstanceOf($node);
|
||||
|
||||
$htmlInput = $this->config->get('html_input');
|
||||
|
||||
return HtmlFilter::filter($node->getLiteral(), $htmlInput);
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration): void
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
|
||||
public function getXmlTagName(Node $node): string
|
||||
{
|
||||
return 'html_inline';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getXmlAttributes(Node $node): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
107
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Inline/ImageRenderer.php
vendored
Normal file
107
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Inline/ImageRenderer.php
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Renderer\Inline;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\Image;
|
||||
use League\CommonMark\Node\Inline\Newline;
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Node\NodeIterator;
|
||||
use League\CommonMark\Node\StringContainerInterface;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
use League\CommonMark\Util\HtmlElement;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
use League\CommonMark\Xml\XmlNodeRendererInterface;
|
||||
use League\Config\ConfigurationAwareInterface;
|
||||
use League\Config\ConfigurationInterface;
|
||||
|
||||
final class ImageRenderer implements NodeRendererInterface, XmlNodeRendererInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @psalm-readonly-allow-private-mutation */
|
||||
private ConfigurationInterface $config;
|
||||
|
||||
/**
|
||||
* @param Image $node
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer): \Stringable
|
||||
{
|
||||
Image::assertInstanceOf($node);
|
||||
|
||||
$attrs = $node->data->get('attributes');
|
||||
|
||||
$forbidUnsafeLinks = ! $this->config->get('allow_unsafe_links');
|
||||
if ($forbidUnsafeLinks && RegexHelper::isLinkPotentiallyUnsafe($node->getUrl())) {
|
||||
$attrs['src'] = '';
|
||||
} else {
|
||||
$attrs['src'] = $node->getUrl();
|
||||
}
|
||||
|
||||
$attrs['alt'] = $this->getAltText($node);
|
||||
|
||||
if (($title = $node->getTitle()) !== null) {
|
||||
$attrs['title'] = $title;
|
||||
}
|
||||
|
||||
return new HtmlElement('img', $attrs, '', true);
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration): void
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
|
||||
public function getXmlTagName(Node $node): string
|
||||
{
|
||||
return 'image';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Image $node
|
||||
*
|
||||
* @return array<string, scalar>
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function getXmlAttributes(Node $node): array
|
||||
{
|
||||
Image::assertInstanceOf($node);
|
||||
|
||||
return [
|
||||
'destination' => $node->getUrl(),
|
||||
'title' => $node->getTitle() ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
private function getAltText(Image $node): string
|
||||
{
|
||||
$altText = '';
|
||||
|
||||
foreach ((new NodeIterator($node)) as $n) {
|
||||
if ($n instanceof StringContainerInterface) {
|
||||
$altText .= $n->getLiteral();
|
||||
} elseif ($n instanceof Newline) {
|
||||
$altText .= "\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $altText;
|
||||
}
|
||||
}
|
||||
89
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Inline/LinkRenderer.php
vendored
Normal file
89
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Inline/LinkRenderer.php
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Renderer\Inline;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\Link;
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
use League\CommonMark\Util\HtmlElement;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
use League\CommonMark\Xml\XmlNodeRendererInterface;
|
||||
use League\Config\ConfigurationAwareInterface;
|
||||
use League\Config\ConfigurationInterface;
|
||||
|
||||
final class LinkRenderer implements NodeRendererInterface, XmlNodeRendererInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @psalm-readonly-allow-private-mutation */
|
||||
private ConfigurationInterface $config;
|
||||
|
||||
/**
|
||||
* @param Link $node
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer): \Stringable
|
||||
{
|
||||
Link::assertInstanceOf($node);
|
||||
|
||||
$attrs = $node->data->get('attributes');
|
||||
|
||||
$forbidUnsafeLinks = ! $this->config->get('allow_unsafe_links');
|
||||
if (! ($forbidUnsafeLinks && RegexHelper::isLinkPotentiallyUnsafe($node->getUrl()))) {
|
||||
$attrs['href'] = $node->getUrl();
|
||||
}
|
||||
|
||||
if (($title = $node->getTitle()) !== null) {
|
||||
$attrs['title'] = $title;
|
||||
}
|
||||
|
||||
if (isset($attrs['target']) && $attrs['target'] === '_blank' && ! isset($attrs['rel'])) {
|
||||
$attrs['rel'] = 'noopener noreferrer';
|
||||
}
|
||||
|
||||
return new HtmlElement('a', $attrs, $childRenderer->renderNodes($node->children()));
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration): void
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
|
||||
public function getXmlTagName(Node $node): string
|
||||
{
|
||||
return 'link';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Link $node
|
||||
*
|
||||
* @return array<string, scalar>
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function getXmlAttributes(Node $node): array
|
||||
{
|
||||
Link::assertInstanceOf($node);
|
||||
|
||||
return [
|
||||
'destination' => $node->getUrl(),
|
||||
'title' => $node->getTitle() ?? '',
|
||||
];
|
||||
}
|
||||
}
|
||||
56
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Inline/StrongRenderer.php
vendored
Normal file
56
vendor/league/commonmark/src/Extension/CommonMark/Renderer/Inline/StrongRenderer.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\CommonMark\Renderer\Inline;
|
||||
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\Strong;
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
use League\CommonMark\Util\HtmlElement;
|
||||
use League\CommonMark\Xml\XmlNodeRendererInterface;
|
||||
|
||||
final class StrongRenderer implements NodeRendererInterface, XmlNodeRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param Strong $node
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer): \Stringable
|
||||
{
|
||||
Strong::assertInstanceOf($node);
|
||||
|
||||
$attrs = $node->data->get('attributes');
|
||||
|
||||
return new HtmlElement('strong', $attrs, $childRenderer->renderNodes($node->children()));
|
||||
}
|
||||
|
||||
public function getXmlTagName(Node $node): string
|
||||
{
|
||||
return 'strong';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getXmlAttributes(Node $node): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
21
vendor/league/commonmark/src/Extension/ConfigurableExtensionInterface.php
vendored
Normal file
21
vendor/league/commonmark/src/Extension/ConfigurableExtensionInterface.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?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\Extension;
|
||||
|
||||
use League\Config\ConfigurationBuilderInterface;
|
||||
|
||||
interface ConfigurableExtensionInterface extends ExtensionInterface
|
||||
{
|
||||
public function configureSchema(ConfigurationBuilderInterface $builder): void;
|
||||
}
|
||||
65
vendor/league/commonmark/src/Extension/DefaultAttributes/ApplyDefaultAttributesProcessor.php
vendored
Normal file
65
vendor/league/commonmark/src/Extension/DefaultAttributes/ApplyDefaultAttributesProcessor.php
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
<?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\Extension\DefaultAttributes;
|
||||
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\Attributes\Util\AttributesHelper;
|
||||
use League\Config\ConfigurationAwareInterface;
|
||||
use League\Config\ConfigurationInterface;
|
||||
|
||||
final class ApplyDefaultAttributesProcessor implements ConfigurationAwareInterface
|
||||
{
|
||||
private ConfigurationInterface $config;
|
||||
|
||||
public function onDocumentParsed(DocumentParsedEvent $event): void
|
||||
{
|
||||
/** @var array<string, array<string, mixed>> $map */
|
||||
$map = $this->config->get('default_attributes');
|
||||
|
||||
// Don't bother iterating if no default attributes are configured
|
||||
if (! $map) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($event->getDocument()->iterator() as $node) {
|
||||
// Check to see if any default attributes were defined
|
||||
if (($attributesToApply = $map[\get_class($node)] ?? []) === []) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$newAttributes = [];
|
||||
foreach ($attributesToApply as $name => $value) {
|
||||
if (\is_callable($value)) {
|
||||
$value = $value($node);
|
||||
// Callables are allowed to return `null` indicating that no changes should be made
|
||||
if ($value !== null) {
|
||||
$newAttributes[$name] = $value;
|
||||
}
|
||||
} else {
|
||||
$newAttributes[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Merge these attributes into the node
|
||||
if (\count($newAttributes) > 0) {
|
||||
$node->data->set('attributes', AttributesHelper::mergeAttributes($node, $newAttributes));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration): void
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
}
|
||||
39
vendor/league/commonmark/src/Extension/DefaultAttributes/DefaultAttributesExtension.php
vendored
Normal file
39
vendor/league/commonmark/src/Extension/DefaultAttributes/DefaultAttributesExtension.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?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\Extension\DefaultAttributes;
|
||||
|
||||
use League\CommonMark\Environment\EnvironmentBuilderInterface;
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\ConfigurableExtensionInterface;
|
||||
use League\Config\ConfigurationBuilderInterface;
|
||||
use Nette\Schema\Expect;
|
||||
|
||||
final class DefaultAttributesExtension implements ConfigurableExtensionInterface
|
||||
{
|
||||
public function configureSchema(ConfigurationBuilderInterface $builder): void
|
||||
{
|
||||
$builder->addSchema('default_attributes', Expect::arrayOf(
|
||||
Expect::arrayOf(
|
||||
Expect::type('string|string[]|bool|callable'), // attribute value(s)
|
||||
'string' // attribute name
|
||||
),
|
||||
'string' // node FQCN
|
||||
)->default([]));
|
||||
}
|
||||
|
||||
public function register(EnvironmentBuilderInterface $environment): void
|
||||
{
|
||||
$environment->addEventListener(DocumentParsedEvent::class, [new ApplyDefaultAttributesProcessor(), 'onDocumentParsed']);
|
||||
}
|
||||
}
|
||||
42
vendor/league/commonmark/src/Extension/DescriptionList/DescriptionListExtension.php
vendored
Normal file
42
vendor/league/commonmark/src/Extension/DescriptionList/DescriptionListExtension.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?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\Extension\DescriptionList;
|
||||
|
||||
use League\CommonMark\Environment\EnvironmentBuilderInterface;
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\DescriptionList\Event\ConsecutiveDescriptionListMerger;
|
||||
use League\CommonMark\Extension\DescriptionList\Event\LooseDescriptionHandler;
|
||||
use League\CommonMark\Extension\DescriptionList\Node\Description;
|
||||
use League\CommonMark\Extension\DescriptionList\Node\DescriptionList;
|
||||
use League\CommonMark\Extension\DescriptionList\Node\DescriptionTerm;
|
||||
use League\CommonMark\Extension\DescriptionList\Parser\DescriptionStartParser;
|
||||
use League\CommonMark\Extension\DescriptionList\Renderer\DescriptionListRenderer;
|
||||
use League\CommonMark\Extension\DescriptionList\Renderer\DescriptionRenderer;
|
||||
use League\CommonMark\Extension\DescriptionList\Renderer\DescriptionTermRenderer;
|
||||
use League\CommonMark\Extension\ExtensionInterface;
|
||||
|
||||
final class DescriptionListExtension implements ExtensionInterface
|
||||
{
|
||||
public function register(EnvironmentBuilderInterface $environment): void
|
||||
{
|
||||
$environment->addBlockStartParser(new DescriptionStartParser());
|
||||
|
||||
$environment->addEventListener(DocumentParsedEvent::class, new LooseDescriptionHandler(), 1001);
|
||||
$environment->addEventListener(DocumentParsedEvent::class, new ConsecutiveDescriptionListMerger(), 1000);
|
||||
|
||||
$environment->addRenderer(DescriptionList::class, new DescriptionListRenderer());
|
||||
$environment->addRenderer(DescriptionTerm::class, new DescriptionTermRenderer());
|
||||
$environment->addRenderer(Description::class, new DescriptionRenderer());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?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\Extension\DescriptionList\Event;
|
||||
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\DescriptionList\Node\DescriptionList;
|
||||
use League\CommonMark\Node\NodeIterator;
|
||||
|
||||
final class ConsecutiveDescriptionListMerger
|
||||
{
|
||||
public function __invoke(DocumentParsedEvent $event): void
|
||||
{
|
||||
foreach ($event->getDocument()->iterator(NodeIterator::FLAG_BLOCKS_ONLY) as $node) {
|
||||
if (! $node instanceof DescriptionList) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! ($prev = $node->previous()) instanceof DescriptionList) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// There's another description list behind this one; merge the current one into that
|
||||
foreach ($node->children() as $child) {
|
||||
$prev->appendChild($child);
|
||||
}
|
||||
|
||||
$node->detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
66
vendor/league/commonmark/src/Extension/DescriptionList/Event/LooseDescriptionHandler.php
vendored
Normal file
66
vendor/league/commonmark/src/Extension/DescriptionList/Event/LooseDescriptionHandler.php
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
<?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\Extension\DescriptionList\Event;
|
||||
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\DescriptionList\Node\Description;
|
||||
use League\CommonMark\Extension\DescriptionList\Node\DescriptionList;
|
||||
use League\CommonMark\Extension\DescriptionList\Node\DescriptionTerm;
|
||||
use League\CommonMark\Node\Block\Paragraph;
|
||||
use League\CommonMark\Node\Inline\Newline;
|
||||
use League\CommonMark\Node\NodeIterator;
|
||||
|
||||
final class LooseDescriptionHandler
|
||||
{
|
||||
public function __invoke(DocumentParsedEvent $event): void
|
||||
{
|
||||
foreach ($event->getDocument()->iterator(NodeIterator::FLAG_BLOCKS_ONLY) as $description) {
|
||||
if (! $description instanceof Description) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Does this description need to be added to a list?
|
||||
if (! $description->parent() instanceof DescriptionList) {
|
||||
$list = new DescriptionList();
|
||||
// Taking any preceding paragraphs with it
|
||||
if (($paragraph = $description->previous()) instanceof Paragraph) {
|
||||
$list->appendChild($paragraph);
|
||||
}
|
||||
|
||||
$description->replaceWith($list);
|
||||
$list->appendChild($description);
|
||||
}
|
||||
|
||||
// Is this description preceded by a paragraph that should really be a term?
|
||||
if (! (($paragraph = $description->previous()) instanceof Paragraph)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Convert the paragraph into one or more terms
|
||||
$term = new DescriptionTerm();
|
||||
$paragraph->replaceWith($term);
|
||||
|
||||
foreach ($paragraph->children() as $child) {
|
||||
if ($child instanceof Newline) {
|
||||
$newTerm = new DescriptionTerm();
|
||||
$term->insertAfter($newTerm);
|
||||
$term = $newTerm;
|
||||
continue;
|
||||
}
|
||||
|
||||
$term->appendChild($child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
39
vendor/league/commonmark/src/Extension/DescriptionList/Node/Description.php
vendored
Normal file
39
vendor/league/commonmark/src/Extension/DescriptionList/Node/Description.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?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\Extension\DescriptionList\Node;
|
||||
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
use League\CommonMark\Node\Block\TightBlockInterface;
|
||||
|
||||
class Description extends AbstractBlock implements TightBlockInterface
|
||||
{
|
||||
private bool $tight;
|
||||
|
||||
public function __construct(bool $tight = false)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->tight = $tight;
|
||||
}
|
||||
|
||||
public function isTight(): bool
|
||||
{
|
||||
return $this->tight;
|
||||
}
|
||||
|
||||
public function setTight(bool $tight): void
|
||||
{
|
||||
$this->tight = $tight;
|
||||
}
|
||||
}
|
||||
20
vendor/league/commonmark/src/Extension/DescriptionList/Node/DescriptionList.php
vendored
Normal file
20
vendor/league/commonmark/src/Extension/DescriptionList/Node/DescriptionList.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?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\Extension\DescriptionList\Node;
|
||||
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
|
||||
class DescriptionList extends AbstractBlock
|
||||
{
|
||||
}
|
||||
20
vendor/league/commonmark/src/Extension/DescriptionList/Node/DescriptionTerm.php
vendored
Normal file
20
vendor/league/commonmark/src/Extension/DescriptionList/Node/DescriptionTerm.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?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\Extension\DescriptionList\Node;
|
||||
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
|
||||
class DescriptionTerm extends AbstractBlock
|
||||
{
|
||||
}
|
||||
71
vendor/league/commonmark/src/Extension/DescriptionList/Parser/DescriptionContinueParser.php
vendored
Normal file
71
vendor/league/commonmark/src/Extension/DescriptionList/Parser/DescriptionContinueParser.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>
|
||||
*
|
||||
* 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\DescriptionList\Parser;
|
||||
|
||||
use League\CommonMark\Extension\DescriptionList\Node\Description;
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
use League\CommonMark\Parser\Block\AbstractBlockContinueParser;
|
||||
use League\CommonMark\Parser\Block\BlockContinue;
|
||||
use League\CommonMark\Parser\Block\BlockContinueParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
|
||||
final class DescriptionContinueParser extends AbstractBlockContinueParser
|
||||
{
|
||||
private Description $block;
|
||||
|
||||
private int $indentation;
|
||||
|
||||
public function __construct(bool $tight, int $indentation)
|
||||
{
|
||||
$this->block = new Description($tight);
|
||||
$this->indentation = $indentation;
|
||||
}
|
||||
|
||||
public function getBlock(): Description
|
||||
{
|
||||
return $this->block;
|
||||
}
|
||||
|
||||
public function tryContinue(Cursor $cursor, BlockContinueParserInterface $activeBlockParser): ?BlockContinue
|
||||
{
|
||||
if ($cursor->isBlank()) {
|
||||
if ($this->block->firstChild() === null) {
|
||||
// Blank line after empty item
|
||||
return BlockContinue::none();
|
||||
}
|
||||
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
|
||||
return BlockContinue::at($cursor);
|
||||
}
|
||||
|
||||
if ($cursor->getIndent() >= $this->indentation) {
|
||||
$cursor->advanceBy($this->indentation, true);
|
||||
|
||||
return BlockContinue::at($cursor);
|
||||
}
|
||||
|
||||
return BlockContinue::none();
|
||||
}
|
||||
|
||||
public function isContainer(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canContain(AbstractBlock $childBlock): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
53
vendor/league/commonmark/src/Extension/DescriptionList/Parser/DescriptionListContinueParser.php
vendored
Normal file
53
vendor/league/commonmark/src/Extension/DescriptionList/Parser/DescriptionListContinueParser.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>
|
||||
*
|
||||
* 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\DescriptionList\Parser;
|
||||
|
||||
use League\CommonMark\Extension\DescriptionList\Node\Description;
|
||||
use League\CommonMark\Extension\DescriptionList\Node\DescriptionList;
|
||||
use League\CommonMark\Extension\DescriptionList\Node\DescriptionTerm;
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
use League\CommonMark\Parser\Block\AbstractBlockContinueParser;
|
||||
use League\CommonMark\Parser\Block\BlockContinue;
|
||||
use League\CommonMark\Parser\Block\BlockContinueParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
|
||||
final class DescriptionListContinueParser extends AbstractBlockContinueParser
|
||||
{
|
||||
private DescriptionList $block;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->block = new DescriptionList();
|
||||
}
|
||||
|
||||
public function getBlock(): DescriptionList
|
||||
{
|
||||
return $this->block;
|
||||
}
|
||||
|
||||
public function tryContinue(Cursor $cursor, BlockContinueParserInterface $activeBlockParser): ?BlockContinue
|
||||
{
|
||||
return BlockContinue::at($cursor);
|
||||
}
|
||||
|
||||
public function isContainer(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canContain(AbstractBlock $childBlock): bool
|
||||
{
|
||||
return $childBlock instanceof DescriptionTerm || $childBlock instanceof Description;
|
||||
}
|
||||
}
|
||||
73
vendor/league/commonmark/src/Extension/DescriptionList/Parser/DescriptionStartParser.php
vendored
Normal file
73
vendor/league/commonmark/src/Extension/DescriptionList/Parser/DescriptionStartParser.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>
|
||||
*
|
||||
* 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\DescriptionList\Parser;
|
||||
|
||||
use League\CommonMark\Extension\DescriptionList\Node\Description;
|
||||
use League\CommonMark\Node\Block\Paragraph;
|
||||
use League\CommonMark\Parser\Block\BlockStart;
|
||||
use League\CommonMark\Parser\Block\BlockStartParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
use League\CommonMark\Parser\MarkdownParserStateInterface;
|
||||
|
||||
final class DescriptionStartParser implements BlockStartParserInterface
|
||||
{
|
||||
public function tryStart(Cursor $cursor, MarkdownParserStateInterface $parserState): ?BlockStart
|
||||
{
|
||||
if ($cursor->isIndented()) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
if ($cursor->match('/^:[ \t]+/') === null) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
$terms = $parserState->getParagraphContent();
|
||||
|
||||
$activeBlock = $parserState->getActiveBlockParser()->getBlock();
|
||||
|
||||
if ($terms !== null && $terms !== '') {
|
||||
// New description; tight; term(s) sitting in pending block that we will replace
|
||||
return BlockStart::of(...[new DescriptionListContinueParser()], ...self::splitTerms($terms), ...[new DescriptionContinueParser(true, $cursor->getPosition())])
|
||||
->at($cursor)
|
||||
->replaceActiveBlockParser();
|
||||
}
|
||||
|
||||
if ($activeBlock instanceof Paragraph && $activeBlock->parent() instanceof Description) {
|
||||
// Additional description in the same list as the parent description
|
||||
return BlockStart::of(new DescriptionContinueParser(true, $cursor->getPosition()))->at($cursor);
|
||||
}
|
||||
|
||||
if ($activeBlock->lastChild() instanceof Paragraph) {
|
||||
// New description; loose; term(s) sitting in previous closed paragraph block
|
||||
return BlockStart::of(new DescriptionContinueParser(false, $cursor->getPosition()))->at($cursor);
|
||||
}
|
||||
|
||||
// No preceding terms
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, DescriptionTermContinueParser>
|
||||
*/
|
||||
private static function splitTerms(string $terms): array
|
||||
{
|
||||
$ret = [];
|
||||
foreach (\explode("\n", $terms) as $term) {
|
||||
$ret[] = new DescriptionTermContinueParser($term);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
52
vendor/league/commonmark/src/Extension/DescriptionList/Parser/DescriptionTermContinueParser.php
vendored
Normal file
52
vendor/league/commonmark/src/Extension/DescriptionList/Parser/DescriptionTermContinueParser.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?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\Extension\DescriptionList\Parser;
|
||||
|
||||
use League\CommonMark\Extension\DescriptionList\Node\DescriptionTerm;
|
||||
use League\CommonMark\Parser\Block\AbstractBlockContinueParser;
|
||||
use League\CommonMark\Parser\Block\BlockContinue;
|
||||
use League\CommonMark\Parser\Block\BlockContinueParserInterface;
|
||||
use League\CommonMark\Parser\Block\BlockContinueParserWithInlinesInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
use League\CommonMark\Parser\InlineParserEngineInterface;
|
||||
|
||||
final class DescriptionTermContinueParser extends AbstractBlockContinueParser implements BlockContinueParserWithInlinesInterface
|
||||
{
|
||||
private DescriptionTerm $block;
|
||||
|
||||
private string $term;
|
||||
|
||||
public function __construct(string $term)
|
||||
{
|
||||
$this->block = new DescriptionTerm();
|
||||
$this->term = $term;
|
||||
}
|
||||
|
||||
public function getBlock(): DescriptionTerm
|
||||
{
|
||||
return $this->block;
|
||||
}
|
||||
|
||||
public function tryContinue(Cursor $cursor, BlockContinueParserInterface $activeBlockParser): ?BlockContinue
|
||||
{
|
||||
return BlockContinue::finished();
|
||||
}
|
||||
|
||||
public function parseInlines(InlineParserEngineInterface $inlineParser): void
|
||||
{
|
||||
if ($this->term !== '') {
|
||||
$inlineParser->parse($this->term, $this->block);
|
||||
}
|
||||
}
|
||||
}
|
||||
39
vendor/league/commonmark/src/Extension/DescriptionList/Renderer/DescriptionListRenderer.php
vendored
Normal file
39
vendor/league/commonmark/src/Extension/DescriptionList/Renderer/DescriptionListRenderer.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?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\Extension\DescriptionList\Renderer;
|
||||
|
||||
use League\CommonMark\Extension\DescriptionList\Node\DescriptionList;
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
use League\CommonMark\Util\HtmlElement;
|
||||
|
||||
final class DescriptionListRenderer implements NodeRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param DescriptionList $node
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer): HtmlElement
|
||||
{
|
||||
DescriptionList::assertInstanceOf($node);
|
||||
|
||||
$separator = $childRenderer->getBlockSeparator();
|
||||
|
||||
return new HtmlElement('dl', [], $separator . $childRenderer->renderNodes($node->children()) . $separator);
|
||||
}
|
||||
}
|
||||
37
vendor/league/commonmark/src/Extension/DescriptionList/Renderer/DescriptionRenderer.php
vendored
Normal file
37
vendor/league/commonmark/src/Extension/DescriptionList/Renderer/DescriptionRenderer.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?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\Extension\DescriptionList\Renderer;
|
||||
|
||||
use League\CommonMark\Extension\DescriptionList\Node\Description;
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
use League\CommonMark\Util\HtmlElement;
|
||||
|
||||
final class DescriptionRenderer implements NodeRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param Description $node
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer): \Stringable
|
||||
{
|
||||
Description::assertInstanceOf($node);
|
||||
|
||||
return new HtmlElement('dd', [], $childRenderer->renderNodes($node->children()));
|
||||
}
|
||||
}
|
||||
37
vendor/league/commonmark/src/Extension/DescriptionList/Renderer/DescriptionTermRenderer.php
vendored
Normal file
37
vendor/league/commonmark/src/Extension/DescriptionList/Renderer/DescriptionTermRenderer.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?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\Extension\DescriptionList\Renderer;
|
||||
|
||||
use League\CommonMark\Extension\DescriptionList\Node\DescriptionTerm;
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
use League\CommonMark\Util\HtmlElement;
|
||||
|
||||
final class DescriptionTermRenderer implements NodeRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param DescriptionTerm $node
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer): \Stringable
|
||||
{
|
||||
DescriptionTerm::assertInstanceOf($node);
|
||||
|
||||
return new HtmlElement('dt', [], $childRenderer->renderNodes($node->children()));
|
||||
}
|
||||
}
|
||||
51
vendor/league/commonmark/src/Extension/DisallowedRawHtml/DisallowedRawHtmlExtension.php
vendored
Normal file
51
vendor/league/commonmark/src/Extension/DisallowedRawHtml/DisallowedRawHtmlExtension.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?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\Extension\DisallowedRawHtml;
|
||||
|
||||
use League\CommonMark\Environment\EnvironmentBuilderInterface;
|
||||
use League\CommonMark\Extension\CommonMark\Node\Block\HtmlBlock;
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\HtmlInline;
|
||||
use League\CommonMark\Extension\CommonMark\Renderer\Block\HtmlBlockRenderer;
|
||||
use League\CommonMark\Extension\CommonMark\Renderer\Inline\HtmlInlineRenderer;
|
||||
use League\CommonMark\Extension\ConfigurableExtensionInterface;
|
||||
use League\Config\ConfigurationBuilderInterface;
|
||||
use Nette\Schema\Expect;
|
||||
|
||||
final class DisallowedRawHtmlExtension implements ConfigurableExtensionInterface
|
||||
{
|
||||
private const DEFAULT_DISALLOWED_TAGS = [
|
||||
'title',
|
||||
'textarea',
|
||||
'style',
|
||||
'xmp',
|
||||
'iframe',
|
||||
'noembed',
|
||||
'noframes',
|
||||
'script',
|
||||
'plaintext',
|
||||
];
|
||||
|
||||
public function configureSchema(ConfigurationBuilderInterface $builder): void
|
||||
{
|
||||
$builder->addSchema('disallowed_raw_html', Expect::structure([
|
||||
'disallowed_tags' => Expect::listOf('string')->default(self::DEFAULT_DISALLOWED_TAGS)->mergeDefaults(false),
|
||||
]));
|
||||
}
|
||||
|
||||
public function register(EnvironmentBuilderInterface $environment): void
|
||||
{
|
||||
$environment->addRenderer(HtmlBlock::class, new DisallowedRawHtmlRenderer(new HtmlBlockRenderer()), 50);
|
||||
$environment->addRenderer(HtmlInline::class, new DisallowedRawHtmlRenderer(new HtmlInlineRenderer()), 50);
|
||||
}
|
||||
}
|
||||
62
vendor/league/commonmark/src/Extension/DisallowedRawHtml/DisallowedRawHtmlRenderer.php
vendored
Normal file
62
vendor/league/commonmark/src/Extension/DisallowedRawHtml/DisallowedRawHtmlRenderer.php
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
<?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\Extension\DisallowedRawHtml;
|
||||
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
use League\Config\ConfigurationAwareInterface;
|
||||
use League\Config\ConfigurationInterface;
|
||||
|
||||
final class DisallowedRawHtmlRenderer implements NodeRendererInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @psalm-readonly */
|
||||
private NodeRendererInterface $innerRenderer;
|
||||
|
||||
/** @psalm-readonly-allow-private-mutation */
|
||||
private ConfigurationInterface $config;
|
||||
|
||||
public function __construct(NodeRendererInterface $innerRenderer)
|
||||
{
|
||||
$this->innerRenderer = $innerRenderer;
|
||||
}
|
||||
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer): ?string
|
||||
{
|
||||
$rendered = (string) $this->innerRenderer->render($node, $childRenderer);
|
||||
|
||||
if ($rendered === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$tags = (array) $this->config->get('disallowed_raw_html/disallowed_tags');
|
||||
if (\count($tags) === 0) {
|
||||
return $rendered;
|
||||
}
|
||||
|
||||
$regex = \sprintf('/<(\/?(?:%s)[ \/>])/i', \implode('|', \array_map('preg_quote', $tags)));
|
||||
|
||||
// Match these types of tags: <title> </title> <title x="sdf"> <title/> <title />
|
||||
return \preg_replace($regex, '<$1', $rendered);
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration): void
|
||||
{
|
||||
$this->config = $configuration;
|
||||
|
||||
if ($this->innerRenderer instanceof ConfigurationAwareInterface) {
|
||||
$this->innerRenderer->setConfiguration($configuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
49
vendor/league/commonmark/src/Extension/Embed/Bridge/OscaroteroEmbedAdapter.php
vendored
Normal file
49
vendor/league/commonmark/src/Extension/Embed/Bridge/OscaroteroEmbedAdapter.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?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\Extension\Embed\Bridge;
|
||||
|
||||
use Embed\Embed as EmbedLib;
|
||||
use League\CommonMark\Extension\Embed\Embed;
|
||||
use League\CommonMark\Extension\Embed\EmbedAdapterInterface;
|
||||
|
||||
final class OscaroteroEmbedAdapter implements EmbedAdapterInterface
|
||||
{
|
||||
private EmbedLib $embedLib;
|
||||
|
||||
public function __construct(?EmbedLib $embed = null)
|
||||
{
|
||||
if ($embed === null) {
|
||||
if (! \class_exists(EmbedLib::class)) {
|
||||
throw new \RuntimeException('The embed/embed package is not installed. Please install it with Composer to use this adapter.');
|
||||
}
|
||||
|
||||
$embed = new EmbedLib();
|
||||
}
|
||||
|
||||
$this->embedLib = $embed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function updateEmbeds(array $embeds): void
|
||||
{
|
||||
$extractors = $this->embedLib->getMulti(...\array_map(static fn (Embed $embed) => $embed->getUrl(), $embeds));
|
||||
foreach ($extractors as $i => $extractor) {
|
||||
if ($extractor->code !== null) {
|
||||
$embeds[$i]->setEmbedCode($extractor->code->html);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
50
vendor/league/commonmark/src/Extension/Embed/DomainFilteringAdapter.php
vendored
Normal file
50
vendor/league/commonmark/src/Extension/Embed/DomainFilteringAdapter.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?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\Extension\Embed;
|
||||
|
||||
class DomainFilteringAdapter implements EmbedAdapterInterface
|
||||
{
|
||||
private EmbedAdapterInterface $decorated;
|
||||
|
||||
private string $regex;
|
||||
|
||||
/**
|
||||
* @param string[] $allowedDomains
|
||||
*/
|
||||
public function __construct(EmbedAdapterInterface $decorated, array $allowedDomains)
|
||||
{
|
||||
$this->decorated = $decorated;
|
||||
$this->regex = self::createRegex($allowedDomains);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function updateEmbeds(array $embeds): void
|
||||
{
|
||||
$this->decorated->updateEmbeds(\array_values(\array_filter($embeds, function (Embed $embed): bool {
|
||||
return \preg_match($this->regex, $embed->getUrl()) === 1;
|
||||
})));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $allowedDomains
|
||||
*/
|
||||
private static function createRegex(array $allowedDomains): string
|
||||
{
|
||||
$allowedDomains = \array_map('preg_quote', $allowedDomains);
|
||||
|
||||
return '/^(?:https?:\/\/)?(?:[^.]+\.)*(' . \implode('|', $allowedDomains) . ')/';
|
||||
}
|
||||
}
|
||||
50
vendor/league/commonmark/src/Extension/Embed/Embed.php
vendored
Normal file
50
vendor/league/commonmark/src/Extension/Embed/Embed.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?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\Extension\Embed;
|
||||
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
|
||||
final class Embed extends AbstractBlock
|
||||
{
|
||||
private string $url;
|
||||
private ?string $embedCode;
|
||||
|
||||
public function __construct(string $url, ?string $embedCode = null)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->url = $url;
|
||||
$this->embedCode = $embedCode;
|
||||
}
|
||||
|
||||
public function getUrl(): string
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function setUrl(string $url): void
|
||||
{
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
public function getEmbedCode(): ?string
|
||||
{
|
||||
return $this->embedCode;
|
||||
}
|
||||
|
||||
public function setEmbedCode(?string $embedCode): void
|
||||
{
|
||||
$this->embedCode = $embedCode;
|
||||
}
|
||||
}
|
||||
25
vendor/league/commonmark/src/Extension/Embed/EmbedAdapterInterface.php
vendored
Normal file
25
vendor/league/commonmark/src/Extension/Embed/EmbedAdapterInterface.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?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\Extension\Embed;
|
||||
|
||||
/**
|
||||
* Interface for a service which updates the embed code(s) for the given array of embeds
|
||||
*/
|
||||
interface EmbedAdapterInterface
|
||||
{
|
||||
/**
|
||||
* @param Embed[] $embeds
|
||||
*/
|
||||
public function updateEmbeds(array $embeds): void;
|
||||
}
|
||||
48
vendor/league/commonmark/src/Extension/Embed/EmbedExtension.php
vendored
Normal file
48
vendor/league/commonmark/src/Extension/Embed/EmbedExtension.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?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\Extension\Embed;
|
||||
|
||||
use League\CommonMark\Environment\EnvironmentBuilderInterface;
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\ConfigurableExtensionInterface;
|
||||
use League\Config\ConfigurationBuilderInterface;
|
||||
use Nette\Schema\Expect;
|
||||
|
||||
final class EmbedExtension implements ConfigurableExtensionInterface
|
||||
{
|
||||
public function configureSchema(ConfigurationBuilderInterface $builder): void
|
||||
{
|
||||
$builder->addSchema('embed', Expect::structure([
|
||||
'adapter' => Expect::type(EmbedAdapterInterface::class),
|
||||
'allowed_domains' => Expect::arrayOf('string')->default([]),
|
||||
'fallback' => Expect::anyOf('link', 'remove')->default('link'),
|
||||
]));
|
||||
}
|
||||
|
||||
public function register(EnvironmentBuilderInterface $environment): void
|
||||
{
|
||||
$adapter = $environment->getConfiguration()->get('embed.adapter');
|
||||
\assert($adapter instanceof EmbedAdapterInterface);
|
||||
|
||||
$allowedDomains = $environment->getConfiguration()->get('embed.allowed_domains');
|
||||
if ($allowedDomains !== []) {
|
||||
$adapter = new DomainFilteringAdapter($adapter, $allowedDomains);
|
||||
}
|
||||
|
||||
$environment
|
||||
->addBlockStartParser(new EmbedStartParser(), 300)
|
||||
->addEventListener(DocumentParsedEvent::class, new EmbedProcessor($adapter, $environment->getConfiguration()->get('embed.fallback')), 1010)
|
||||
->addRenderer(Embed::class, new EmbedRenderer());
|
||||
}
|
||||
}
|
||||
62
vendor/league/commonmark/src/Extension/Embed/EmbedParser.php
vendored
Normal file
62
vendor/league/commonmark/src/Extension/Embed/EmbedParser.php
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
<?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\Extension\Embed;
|
||||
|
||||
use League\CommonMark\Node\Block\AbstractBlock;
|
||||
use League\CommonMark\Parser\Block\BlockContinue;
|
||||
use League\CommonMark\Parser\Block\BlockContinueParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
|
||||
class EmbedParser implements BlockContinueParserInterface
|
||||
{
|
||||
private Embed $embed;
|
||||
|
||||
public function __construct(string $url)
|
||||
{
|
||||
$this->embed = new Embed($url);
|
||||
}
|
||||
|
||||
public function getBlock(): AbstractBlock
|
||||
{
|
||||
return $this->embed;
|
||||
}
|
||||
|
||||
public function isContainer(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canHaveLazyContinuationLines(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canContain(AbstractBlock $childBlock): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function tryContinue(Cursor $cursor, BlockContinueParserInterface $activeBlockParser): ?BlockContinue
|
||||
{
|
||||
return BlockContinue::none();
|
||||
}
|
||||
|
||||
public function addLine(string $line): void
|
||||
{
|
||||
}
|
||||
|
||||
public function closeBlock(): void
|
||||
{
|
||||
}
|
||||
}
|
||||
70
vendor/league/commonmark/src/Extension/Embed/EmbedProcessor.php
vendored
Normal file
70
vendor/league/commonmark/src/Extension/Embed/EmbedProcessor.php
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
<?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\Extension\Embed;
|
||||
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\Link;
|
||||
use League\CommonMark\Node\Block\Paragraph;
|
||||
use League\CommonMark\Node\Inline\Text;
|
||||
use League\CommonMark\Node\NodeIterator;
|
||||
|
||||
final class EmbedProcessor
|
||||
{
|
||||
public const FALLBACK_REMOVE = 'remove';
|
||||
public const FALLBACK_LINK = 'link';
|
||||
|
||||
private EmbedAdapterInterface $adapter;
|
||||
private string $fallback;
|
||||
|
||||
public function __construct(EmbedAdapterInterface $adapter, string $fallback = self::FALLBACK_REMOVE)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
$this->fallback = $fallback;
|
||||
}
|
||||
|
||||
public function __invoke(DocumentParsedEvent $event): void
|
||||
{
|
||||
$document = $event->getDocument();
|
||||
$embeds = [];
|
||||
foreach (new NodeIterator($document) as $node) {
|
||||
if (! ($node instanceof Embed)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($node->parent() !== $document) {
|
||||
$replacement = new Paragraph();
|
||||
$replacement->appendChild(new Text($node->getUrl()));
|
||||
$node->replaceWith($replacement);
|
||||
} else {
|
||||
$embeds[] = $node;
|
||||
}
|
||||
}
|
||||
|
||||
$this->adapter->updateEmbeds($embeds);
|
||||
|
||||
foreach ($embeds as $embed) {
|
||||
if ($embed->getEmbedCode() !== null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->fallback === self::FALLBACK_REMOVE) {
|
||||
$embed->detach();
|
||||
} elseif ($this->fallback === self::FALLBACK_LINK) {
|
||||
$paragraph = new Paragraph();
|
||||
$paragraph->appendChild(new Link($embed->getUrl(), $embed->getUrl()));
|
||||
$embed->replaceWith($paragraph);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
35
vendor/league/commonmark/src/Extension/Embed/EmbedRenderer.php
vendored
Normal file
35
vendor/league/commonmark/src/Extension/Embed/EmbedRenderer.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?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\Extension\Embed;
|
||||
|
||||
use League\CommonMark\Node\Node;
|
||||
use League\CommonMark\Renderer\ChildNodeRendererInterface;
|
||||
use League\CommonMark\Renderer\NodeRendererInterface;
|
||||
|
||||
class EmbedRenderer implements NodeRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param Embed $node
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function render(Node $node, ChildNodeRendererInterface $childRenderer)
|
||||
{
|
||||
Embed::assertInstanceOf($node);
|
||||
|
||||
return $node->getEmbedCode() ?? '';
|
||||
}
|
||||
}
|
||||
53
vendor/league/commonmark/src/Extension/Embed/EmbedStartParser.php
vendored
Normal file
53
vendor/league/commonmark/src/Extension/Embed/EmbedStartParser.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<?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\Extension\Embed;
|
||||
|
||||
use League\CommonMark\Parser\Block\BlockStart;
|
||||
use League\CommonMark\Parser\Block\BlockStartParserInterface;
|
||||
use League\CommonMark\Parser\Cursor;
|
||||
use League\CommonMark\Parser\MarkdownParserStateInterface;
|
||||
use League\CommonMark\Util\LinkParserHelper;
|
||||
|
||||
class EmbedStartParser implements BlockStartParserInterface
|
||||
{
|
||||
public function tryStart(Cursor $cursor, MarkdownParserStateInterface $parserState): ?BlockStart
|
||||
{
|
||||
if ($cursor->isIndented() || $parserState->getParagraphContent() !== null || ! ($parserState->getActiveBlockParser()->isContainer())) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
// 0-3 leading spaces are okay
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
|
||||
// The line must begin with "https://"
|
||||
if (! str_starts_with($cursor->getRemainder(), 'https://')) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
// A valid link must be found next
|
||||
if (($dest = LinkParserHelper::parseLinkDestination($cursor)) === null) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
// Skip any trailing whitespace
|
||||
$cursor->advanceToNextNonSpaceOrTab();
|
||||
|
||||
// We must be at the end of the line; otherwise, this link was not by itself
|
||||
if (! $cursor->isAtEnd()) {
|
||||
return BlockStart::none();
|
||||
}
|
||||
|
||||
return BlockStart::of(new EmbedParser($dest))->at($cursor);
|
||||
}
|
||||
}
|
||||
24
vendor/league/commonmark/src/Extension/ExtensionInterface.php
vendored
Normal file
24
vendor/league/commonmark/src/Extension/ExtensionInterface.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* 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\Environment\EnvironmentBuilderInterface;
|
||||
|
||||
interface ExtensionInterface
|
||||
{
|
||||
public function register(EnvironmentBuilderInterface $environment): void;
|
||||
}
|
||||
47
vendor/league/commonmark/src/Extension/ExternalLink/ExternalLinkExtension.php
vendored
Normal file
47
vendor/league/commonmark/src/Extension/ExternalLink/ExternalLinkExtension.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?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\Extension\ExternalLink;
|
||||
|
||||
use League\CommonMark\Environment\EnvironmentBuilderInterface;
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\ConfigurableExtensionInterface;
|
||||
use League\Config\ConfigurationBuilderInterface;
|
||||
use Nette\Schema\Expect;
|
||||
|
||||
final class ExternalLinkExtension implements ConfigurableExtensionInterface
|
||||
{
|
||||
public function configureSchema(ConfigurationBuilderInterface $builder): void
|
||||
{
|
||||
$applyOptions = [
|
||||
ExternalLinkProcessor::APPLY_NONE,
|
||||
ExternalLinkProcessor::APPLY_ALL,
|
||||
ExternalLinkProcessor::APPLY_INTERNAL,
|
||||
ExternalLinkProcessor::APPLY_EXTERNAL,
|
||||
];
|
||||
|
||||
$builder->addSchema('external_link', Expect::structure([
|
||||
'internal_hosts' => Expect::type('string|string[]'),
|
||||
'open_in_new_window' => Expect::bool(false),
|
||||
'html_class' => Expect::string()->default(''),
|
||||
'nofollow' => Expect::anyOf(...$applyOptions)->default(ExternalLinkProcessor::APPLY_NONE),
|
||||
'noopener' => Expect::anyOf(...$applyOptions)->default(ExternalLinkProcessor::APPLY_EXTERNAL),
|
||||
'noreferrer' => Expect::anyOf(...$applyOptions)->default(ExternalLinkProcessor::APPLY_EXTERNAL),
|
||||
]));
|
||||
}
|
||||
|
||||
public function register(EnvironmentBuilderInterface $environment): void
|
||||
{
|
||||
$environment->addEventListener(DocumentParsedEvent::class, new ExternalLinkProcessor($environment->getConfiguration()), -50);
|
||||
}
|
||||
}
|
||||
114
vendor/league/commonmark/src/Extension/ExternalLink/ExternalLinkProcessor.php
vendored
Normal file
114
vendor/league/commonmark/src/Extension/ExternalLink/ExternalLinkProcessor.php
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
<?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\Extension\ExternalLink;
|
||||
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\CommonMark\Node\Inline\Link;
|
||||
use League\Config\ConfigurationInterface;
|
||||
|
||||
final class ExternalLinkProcessor
|
||||
{
|
||||
public const APPLY_NONE = '';
|
||||
public const APPLY_ALL = 'all';
|
||||
public const APPLY_EXTERNAL = 'external';
|
||||
public const APPLY_INTERNAL = 'internal';
|
||||
|
||||
/** @psalm-readonly */
|
||||
private ConfigurationInterface $config;
|
||||
|
||||
public function __construct(ConfigurationInterface $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function __invoke(DocumentParsedEvent $e): void
|
||||
{
|
||||
$internalHosts = $this->config->get('external_link/internal_hosts');
|
||||
$openInNewWindow = $this->config->get('external_link/open_in_new_window');
|
||||
$classes = $this->config->get('external_link/html_class');
|
||||
|
||||
foreach ($e->getDocument()->iterator() as $link) {
|
||||
if (! ($link instanceof Link)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$host = \parse_url($link->getUrl(), PHP_URL_HOST);
|
||||
if (! \is_string($host)) {
|
||||
// Something is terribly wrong with this URL
|
||||
continue;
|
||||
}
|
||||
|
||||
if (self::hostMatches($host, $internalHosts)) {
|
||||
$link->data->set('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->set('external', true);
|
||||
$this->applyRelAttribute($link, true);
|
||||
|
||||
if ($openInNewWindow) {
|
||||
$link->data->set('attributes/target', '_blank');
|
||||
}
|
||||
|
||||
if ($classes !== '') {
|
||||
$link->data->append('attributes/class', $classes);
|
||||
}
|
||||
}
|
||||
|
||||
private function applyRelAttribute(Link $link, bool $isExternal): void
|
||||
{
|
||||
$options = [
|
||||
'nofollow' => $this->config->get('external_link/nofollow'),
|
||||
'noopener' => $this->config->get('external_link/noopener'),
|
||||
'noreferrer' => $this->config->get('external_link/noreferrer'),
|
||||
];
|
||||
|
||||
foreach ($options as $type => $option) {
|
||||
switch (true) {
|
||||
case $option === self::APPLY_ALL:
|
||||
case $isExternal && $option === self::APPLY_EXTERNAL:
|
||||
case ! $isExternal && $option === self::APPLY_INTERNAL:
|
||||
$link->data->append('attributes/rel', $type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal This method is only public so we can easily test it. DO NOT USE THIS OUTSIDE OF THIS EXTENSION!
|
||||
*
|
||||
* @param mixed $compareTo
|
||||
*/
|
||||
public static function hostMatches(string $host, $compareTo): bool
|
||||
{
|
||||
foreach ((array) $compareTo as $c) {
|
||||
if (\strpos($c, '/') === 0) {
|
||||
if (\preg_match($c, $host)) {
|
||||
return true;
|
||||
}
|
||||
} elseif ($c === $host) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
62
vendor/league/commonmark/src/Extension/Footnote/Event/AnonymousFootnotesListener.php
vendored
Normal file
62
vendor/league/commonmark/src/Extension/Footnote/Event/AnonymousFootnotesListener.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\Event;
|
||||
|
||||
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\Node\Block\Paragraph;
|
||||
use League\CommonMark\Node\Inline\Text;
|
||||
use League\CommonMark\Reference\Reference;
|
||||
use League\Config\ConfigurationAwareInterface;
|
||||
use League\Config\ConfigurationInterface;
|
||||
|
||||
final class AnonymousFootnotesListener implements ConfigurationAwareInterface
|
||||
{
|
||||
private ConfigurationInterface $config;
|
||||
|
||||
public function onDocumentParsed(DocumentParsedEvent $event): void
|
||||
{
|
||||
$document = $event->getDocument();
|
||||
foreach ($document->iterator() as $node) {
|
||||
if (! $node instanceof FootnoteRef || ($text = $node->getContent()) === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Anonymous footnote needs to create a footnote from its content
|
||||
$existingReference = $node->getReference();
|
||||
$newReference = new Reference(
|
||||
$existingReference->getLabel(),
|
||||
'#' . $this->config->get('footnote/ref_id_prefix') . $existingReference->getLabel(),
|
||||
$existingReference->getTitle()
|
||||
);
|
||||
|
||||
$paragraph = new Paragraph();
|
||||
$paragraph->appendChild(new Text($text));
|
||||
$paragraph->appendChild(new FootnoteBackref($newReference));
|
||||
|
||||
$footnote = new Footnote($newReference);
|
||||
$footnote->appendChild($paragraph);
|
||||
|
||||
$document->appendChild($footnote);
|
||||
}
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration): void
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
}
|
||||
68
vendor/league/commonmark/src/Extension/Footnote/Event/FixOrphanedFootnotesAndRefsListener.php
vendored
Normal file
68
vendor/league/commonmark/src/Extension/Footnote/Event/FixOrphanedFootnotesAndRefsListener.php
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
<?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.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\CommonMark\Extension\Footnote\Event;
|
||||
|
||||
use League\CommonMark\Event\DocumentParsedEvent;
|
||||
use League\CommonMark\Extension\Footnote\Node\Footnote;
|
||||
use League\CommonMark\Extension\Footnote\Node\FootnoteRef;
|
||||
use League\CommonMark\Node\Block\Document;
|
||||
use League\CommonMark\Node\Inline\Text;
|
||||
|
||||
final class FixOrphanedFootnotesAndRefsListener
|
||||
{
|
||||
public function onDocumentParsed(DocumentParsedEvent $event): void
|
||||
{
|
||||
$document = $event->getDocument();
|
||||
$map = $this->buildMapOfKnownFootnotesAndRefs($document);
|
||||
|
||||
foreach ($map['_flat'] as $node) {
|
||||
if ($node instanceof FootnoteRef && ! isset($map[Footnote::class][$node->getReference()->getLabel()])) {
|
||||
// Found an orphaned FootnoteRef without a corresponding Footnote
|
||||
// Restore the original footnote ref text
|
||||
$node->replaceWith(new Text(\sprintf('[^%s]', $node->getReference()->getLabel())));
|
||||
}
|
||||
|
||||
// phpcs:disable SlevomatCodingStandard.ControlStructures.EarlyExit.EarlyExitNotUsed
|
||||
if ($node instanceof Footnote && ! isset($map[FootnoteRef::class][$node->getReference()->getLabel()])) {
|
||||
// Found an orphaned Footnote without a corresponding FootnoteRef
|
||||
// Remove the footnote
|
||||
$node->detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @phpstan-ignore-next-line */
|
||||
private function buildMapOfKnownFootnotesAndRefs(Document $document): array // @phpcs:ignore
|
||||
{
|
||||
$map = [
|
||||
Footnote::class => [],
|
||||
FootnoteRef::class => [],
|
||||
'_flat' => [],
|
||||
];
|
||||
|
||||
foreach ($document->iterator() as $node) {
|
||||
if ($node instanceof Footnote) {
|
||||
$map[Footnote::class][$node->getReference()->getLabel()] = true;
|
||||
|
||||
$map['_flat'][] = $node;
|
||||
} elseif ($node instanceof FootnoteRef) {
|
||||
$map[FootnoteRef::class][$node->getReference()->getLabel()] = true;
|
||||
|
||||
$map['_flat'][] = $node;
|
||||
}
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
}
|
||||
106
vendor/league/commonmark/src/Extension/Footnote/Event/GatherFootnotesListener.php
vendored
Normal file
106
vendor/league/commonmark/src/Extension/Footnote/Event/GatherFootnotesListener.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>
|
||||
* (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\Footnote;
|
||||
use League\CommonMark\Extension\Footnote\Node\FootnoteBackref;
|
||||
use League\CommonMark\Extension\Footnote\Node\FootnoteContainer;
|
||||
use League\CommonMark\Node\Block\Document;
|
||||
use League\CommonMark\Node\NodeIterator;
|
||||
use League\CommonMark\Reference\Reference;
|
||||
use League\Config\ConfigurationAwareInterface;
|
||||
use League\Config\ConfigurationInterface;
|
||||
|
||||
final class GatherFootnotesListener implements ConfigurationAwareInterface
|
||||
{
|
||||
private ConfigurationInterface $config;
|
||||
|
||||
public function onDocumentParsed(DocumentParsedEvent $event): void
|
||||
{
|
||||
$document = $event->getDocument();
|
||||
$footnotes = [];
|
||||
|
||||
foreach ($document->iterator(NodeIterator::FLAG_BLOCKS_ONLY) as $node) {
|
||||
if (! $node instanceof Footnote) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Look for existing reference with footnote label
|
||||
$ref = $document->getReferenceMap()->get($node->getReference()->getLabel());
|
||||
if ($ref !== null) {
|
||||
// Use numeric title to get footnotes order
|
||||
$footnotes[(int) $ref->getTitle()] = $node;
|
||||
} else {
|
||||
// Footnote call is missing, append footnote at the end
|
||||
$footnotes[\PHP_INT_MAX] = $node;
|
||||
}
|
||||
|
||||
$key = '#' . $this->config->get('footnote/footnote_id_prefix') . $node->getReference()->getDestination();
|
||||
if ($document->data->has($key)) {
|
||||
$this->createBackrefs($node, $document->data->get($key));
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for all footnote refs pointing to this footnote and create each footnote backrefs.
|
||||
*
|
||||
* @param Footnote $node The target footnote
|
||||
* @param Reference[] $backrefs References to create backrefs for
|
||||
*/
|
||||
private function createBackrefs(Footnote $node, array $backrefs): void
|
||||
{
|
||||
// Backrefs should be added to the child paragraph
|
||||
$target = $node->lastChild();
|
||||
if ($target === null) {
|
||||
// This should never happen, but you never know
|
||||
$target = $node;
|
||||
}
|
||||
|
||||
foreach ($backrefs as $backref) {
|
||||
$target->appendChild(new FootnoteBackref(new Reference(
|
||||
$backref->getLabel(),
|
||||
'#' . $this->config->get('footnote/ref_id_prefix') . $backref->getLabel(),
|
||||
$backref->getTitle()
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration): void
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
}
|
||||
75
vendor/league/commonmark/src/Extension/Footnote/Event/NumberFootnotesListener.php
vendored
Normal file
75
vendor/league/commonmark/src/Extension/Footnote/Event/NumberFootnotesListener.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\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();
|
||||
$nextCounter = 1;
|
||||
$usedLabels = [];
|
||||
$usedCounters = [];
|
||||
|
||||
foreach ($document->iterator() as $node) {
|
||||
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 .= '__' . ++$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()->add($newReference);
|
||||
|
||||
/*
|
||||
* Store created references in document for
|
||||
* creating FootnoteBackrefs
|
||||
*/
|
||||
$document->data->append($existingReference->getDestination(), $newReference);
|
||||
|
||||
$usedLabels[$label] = 1;
|
||||
$usedCounters[$label] = $nextCounter;
|
||||
|
||||
if ($canIncrementCounter) {
|
||||
$nextCounter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user