Primo Committ
This commit is contained in:
355
vendor/league/commonmark/src/Util/ArrayCollection.php
vendored
Normal file
355
vendor/league/commonmark/src/Util/ArrayCollection.php
vendored
Normal file
@@ -0,0 +1,355 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Util;
|
||||
|
||||
/**
|
||||
* Array collection
|
||||
*
|
||||
* Provides a wrapper around a standard PHP array.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @phpstan-template TKey
|
||||
* @phpstan-template TValue
|
||||
* @phpstan-implements \IteratorAggregate<TKey, TValue>
|
||||
* @phpstan-implements \ArrayAccess<TKey, TValue>
|
||||
*/
|
||||
class ArrayCollection implements \IteratorAggregate, \Countable, \ArrayAccess
|
||||
{
|
||||
/**
|
||||
* @var array<int|string, mixed>
|
||||
* @phpstan-var array<TKey, TValue>
|
||||
*/
|
||||
private $elements;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array<int|string, mixed> $elements
|
||||
*
|
||||
* @phpstan-param array<TKey, TValue> $elements
|
||||
*/
|
||||
public function __construct(array $elements = [])
|
||||
{
|
||||
$this->elements = $elements;
|
||||
|
||||
if (self::class !== static::class) {
|
||||
@\trigger_error('Extending the ArrayCollection class is deprecated in league/commonmark 1.6 and will not be allowed in 2.0', \E_USER_DEPRECATED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|false
|
||||
*
|
||||
* @phpstan-return TValue|false
|
||||
*/
|
||||
public function first()
|
||||
{
|
||||
return \reset($this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|false
|
||||
*
|
||||
* @phpstan-return TValue|false
|
||||
*/
|
||||
public function last()
|
||||
{
|
||||
return \end($this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an external iterator
|
||||
*
|
||||
* @return \ArrayIterator<int|string, mixed>
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $element
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @phpstan-param TValue $element
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function add($element): bool
|
||||
{
|
||||
@trigger_error(sprintf('The "%s:%s" method is deprecated since league/commonmark 1.4, use "%s" instead.', self::class, 'add()', '$collection[] = $value'), E_USER_DEPRECATED);
|
||||
|
||||
$this->elements[] = $element;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string $key
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @phpstan-param TKey $key
|
||||
* @phpstan-param TValue $value
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
@trigger_error(sprintf('The "%s:%s" method is deprecated since league/commonmark 1.4, use "%s" instead.', self::class, 'set()', '$collection[$key] = $value'), E_USER_DEPRECATED);
|
||||
|
||||
$this->offsetSet($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string $key
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @phpstan-param TKey $key
|
||||
*
|
||||
* @phpstan-return TValue|null
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
@trigger_error(sprintf('The "%s:%s" method is deprecated since league/commonmark 1.4, use "%s" instead.', self::class, 'get()', '$collection[$key]'), E_USER_DEPRECATED);
|
||||
|
||||
return $this->offsetGet($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string $key
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @phpstan-param TKey $key
|
||||
*
|
||||
* @phpstan-return TValue|null
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function remove($key)
|
||||
{
|
||||
@trigger_error(sprintf('The "%s:%s" method is deprecated since league/commonmark 1.4, use "%s" instead.', self::class, 'remove()', 'unset($collection[$key])'), E_USER_DEPRECATED);
|
||||
|
||||
if (!\array_key_exists($key, $this->elements)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$removed = $this->elements[$key];
|
||||
unset($this->elements[$key]);
|
||||
|
||||
return $removed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
@trigger_error(sprintf('The "%s:%s" method is deprecated since league/commonmark 1.4, use "%s" instead.', self::class, 'isEmpty()', 'count($collection) === 0'), E_USER_DEPRECATED);
|
||||
|
||||
return empty($this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $element
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @phpstan-param TValue $element
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function contains($element): bool
|
||||
{
|
||||
@trigger_error(sprintf('The "%s:%s" method is deprecated since league/commonmark 1.4, use "%s" instead.', self::class, 'contains()', 'in_array($value, $collection->toArray(), true)'), E_USER_DEPRECATED);
|
||||
|
||||
return \in_array($element, $this->elements, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $element
|
||||
*
|
||||
* @return mixed|false
|
||||
*
|
||||
* @phpstan-param TValue $element
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function indexOf($element)
|
||||
{
|
||||
@trigger_error(sprintf('The "%s:%s" method is deprecated since league/commonmark 1.4, use "%s" instead.', self::class, 'indexOf()', 'array_search($value, $collection->toArray(), true)'), E_USER_DEPRECATED);
|
||||
|
||||
return \array_search($element, $this->elements, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string $key
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @phpstan-param TKey $key
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function containsKey($key): bool
|
||||
{
|
||||
@trigger_error(sprintf('The "%s:%s" method is deprecated since league/commonmark 1.4, use "%s" instead.', self::class, 'containsKey()', 'isset($collection[$key])'), E_USER_DEPRECATED);
|
||||
|
||||
return \array_key_exists($key, $this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count elements of an object
|
||||
*
|
||||
* @return int The count as an integer.
|
||||
*/
|
||||
public function count(): int
|
||||
{
|
||||
return \count($this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether an offset exists
|
||||
*
|
||||
* @param int|string $offset An offset to check for.
|
||||
*
|
||||
* @return bool true on success or false on failure.
|
||||
*
|
||||
* @phpstan-param TKey $offset
|
||||
*/
|
||||
public function offsetExists($offset): bool
|
||||
{
|
||||
return \array_key_exists($offset, $this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset to retrieve
|
||||
*
|
||||
* @param int|string $offset
|
||||
*
|
||||
* @return mixed|null
|
||||
*
|
||||
* @phpstan-param TKey $offset
|
||||
*
|
||||
* @phpstan-return TValue|null
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->elements[$offset] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset to set
|
||||
*
|
||||
* @param int|string|null $offset The offset to assign the value to.
|
||||
* @param mixed $value The value to set.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @phpstan-param TKey|null $offset
|
||||
* @phpstan-param TValue $value
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if ($offset === null) {
|
||||
$this->elements[] = $value;
|
||||
} else {
|
||||
$this->elements[$offset] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset to unset
|
||||
*
|
||||
* @param int|string $offset The offset to unset.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @phpstan-param TKey $offset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
if (!\array_key_exists($offset, $this->elements)) {
|
||||
return;
|
||||
}
|
||||
|
||||
unset($this->elements[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a subset of the array
|
||||
*
|
||||
* @param int $offset
|
||||
* @param int|null $length
|
||||
*
|
||||
* @return array<int|string, mixed>
|
||||
*
|
||||
* @phpstan-return array<TKey, TValue>
|
||||
*/
|
||||
public function slice(int $offset, ?int $length = null): array
|
||||
{
|
||||
return \array_slice($this->elements, $offset, $length, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int|string, mixed>
|
||||
*
|
||||
* @phpstan-return array<TKey, TValue>
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return $this->elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int|string, mixed> $elements
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @phpstan-param array<TKey, TValue> $elements
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function replaceWith(array $elements)
|
||||
{
|
||||
@trigger_error(sprintf('The "%s:%s" method is deprecated since league/commonmark 1.4.', self::class, 'replaceWith()'), E_USER_DEPRECATED);
|
||||
|
||||
$this->elements = $elements;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function removeGaps()
|
||||
{
|
||||
@trigger_error(sprintf('The "%s:%s" method is deprecated since league/commonmark 1.4.', self::class, 'removeGaps()'), E_USER_DEPRECATED);
|
||||
|
||||
$this->elements = \array_filter($this->elements);
|
||||
}
|
||||
}
|
||||
122
vendor/league/commonmark/src/Util/Configuration.php
vendored
Normal file
122
vendor/league/commonmark/src/Util/Configuration.php
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Util;
|
||||
|
||||
final class Configuration implements ConfigurationInterface
|
||||
{
|
||||
/** @var array<string, mixed> */
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $config
|
||||
*/
|
||||
public function __construct(array $config = [])
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function merge(array $config = [])
|
||||
{
|
||||
$this->config = \array_replace_recursive($this->config, $config);
|
||||
}
|
||||
|
||||
public function replace(array $config = [])
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function get(?string $key = null, $default = null)
|
||||
{
|
||||
if ($key === null) {
|
||||
@\trigger_error('Calling Configuration::get() without a $key is deprecated in league/commonmark 1.6 and will not be allowed in 2.0', \E_USER_DEPRECATED);
|
||||
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
// accept a/b/c as ['a']['b']['c']
|
||||
if (\strpos($key, '/')) {
|
||||
return $this->getConfigByPath($key, $default);
|
||||
}
|
||||
|
||||
if (!isset($this->config[$key])) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $this->config[$key];
|
||||
}
|
||||
|
||||
public function set(string $key, $value = null)
|
||||
{
|
||||
if (\func_num_args() === 1) {
|
||||
@\trigger_error('Calling Configuration::set() without a $value is deprecated in league/commonmark 1.6 and will not be allowed in 2.0', \E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
// accept a/b/c as ['a']['b']['c']
|
||||
if (\strpos($key, '/')) {
|
||||
$this->setByPath($key, $value);
|
||||
}
|
||||
|
||||
$this->config[$key] = $value;
|
||||
}
|
||||
|
||||
public function exists(string $key): bool
|
||||
{
|
||||
return $this->getConfigByPath($key, self::MISSING) !== self::MISSING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $keyPath
|
||||
* @param string|null $default
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
private function getConfigByPath(string $keyPath, $default = null)
|
||||
{
|
||||
$keyArr = \explode('/', $keyPath);
|
||||
$data = $this->config;
|
||||
foreach ($keyArr as $k) {
|
||||
if (!\is_array($data) || !isset($data[$k])) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$data = $data[$k];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $keyPath
|
||||
* @param string|null $value
|
||||
*/
|
||||
private function setByPath(string $keyPath, $value = null): void
|
||||
{
|
||||
$keyArr = \explode('/', $keyPath);
|
||||
$pointer = &$this->config;
|
||||
while (($k = \array_shift($keyArr)) !== null) {
|
||||
if (!\is_array($pointer)) {
|
||||
$pointer = [];
|
||||
}
|
||||
|
||||
if (!isset($pointer[$k])) {
|
||||
$pointer[$k] = null;
|
||||
}
|
||||
|
||||
$pointer = &$pointer[$k];
|
||||
}
|
||||
|
||||
$pointer = $value;
|
||||
}
|
||||
}
|
||||
25
vendor/league/commonmark/src/Util/ConfigurationAwareInterface.php
vendored
Normal file
25
vendor/league/commonmark/src/Util/ConfigurationAwareInterface.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Util;
|
||||
|
||||
/**
|
||||
* Implement this class to inject the configuration where needed
|
||||
*/
|
||||
interface ConfigurationAwareInterface
|
||||
{
|
||||
/**
|
||||
* @param ConfigurationInterface $configuration
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setConfiguration(ConfigurationInterface $configuration);
|
||||
}
|
||||
64
vendor/league/commonmark/src/Util/ConfigurationInterface.php
vendored
Normal file
64
vendor/league/commonmark/src/Util/ConfigurationInterface.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Util;
|
||||
|
||||
interface ConfigurationInterface
|
||||
{
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public const MISSING = '833f2700-af8d-49d4-9171-4b5f12d3bfbc';
|
||||
|
||||
/**
|
||||
* Merge an existing array into the current configuration
|
||||
*
|
||||
* @param array<string, mixed> $config
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function merge(array $config = []);
|
||||
|
||||
/**
|
||||
* Replace the entire array with something else
|
||||
*
|
||||
* @param array<string, mixed> $config
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function replace(array $config = []);
|
||||
|
||||
/**
|
||||
* Return the configuration value at the given key, or $default if no such config exists
|
||||
*
|
||||
* The key can be a string or a slash-delimited path to a nested value
|
||||
*
|
||||
* @param string|null $key
|
||||
* @param mixed|null $default
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function get(?string $key = null, $default = null);
|
||||
|
||||
/**
|
||||
* Set the configuration value at the given key
|
||||
*
|
||||
* The key can be a string or a slash-delimited path to a nested value
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed|null $value
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set(string $key, $value = null);
|
||||
}
|
||||
2303
vendor/league/commonmark/src/Util/Html5Entities.php
vendored
Normal file
2303
vendor/league/commonmark/src/Util/Html5Entities.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
63
vendor/league/commonmark/src/Util/Html5EntityDecoder.php
vendored
Normal file
63
vendor/league/commonmark/src/Util/Html5EntityDecoder.php
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* 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\Util;
|
||||
|
||||
final class Html5EntityDecoder
|
||||
{
|
||||
public static function decode(string $entity): string
|
||||
{
|
||||
if (\substr($entity, -1) !== ';') {
|
||||
return $entity;
|
||||
}
|
||||
|
||||
if (\substr($entity, 0, 2) === '&#') {
|
||||
if (\strtolower(\substr($entity, 2, 1)) === 'x') {
|
||||
return self::fromHex(\substr($entity, 3, -1));
|
||||
}
|
||||
|
||||
return self::fromDecimal(\substr($entity, 2, -1));
|
||||
}
|
||||
|
||||
return \html_entity_decode($entity, \ENT_QUOTES | \ENT_HTML5, 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $number
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function fromDecimal($number): string
|
||||
{
|
||||
// Only convert code points within planes 0-2, excluding NULL
|
||||
if (empty($number) || $number > 0x2FFFF) {
|
||||
return self::fromHex('fffd');
|
||||
}
|
||||
|
||||
$entity = '&#' . $number . ';';
|
||||
|
||||
$converted = \mb_decode_numericentity($entity, [0x0, 0x2FFFF, 0, 0xFFFF], 'UTF-8');
|
||||
|
||||
if ($converted === $entity) {
|
||||
return self::fromHex('fffd');
|
||||
}
|
||||
|
||||
return $converted;
|
||||
}
|
||||
|
||||
private static function fromHex(string $hexChars): string
|
||||
{
|
||||
return self::fromDecimal(\hexdec($hexChars));
|
||||
}
|
||||
}
|
||||
125
vendor/league/commonmark/src/Util/LinkParserHelper.php
vendored
Normal file
125
vendor/league/commonmark/src/Util/LinkParserHelper.php
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Util;
|
||||
|
||||
use League\CommonMark\Cursor;
|
||||
|
||||
final class LinkParserHelper
|
||||
{
|
||||
/**
|
||||
* Attempt to parse link destination
|
||||
*
|
||||
* @param Cursor $cursor
|
||||
*
|
||||
* @return null|string The string, or null if no match
|
||||
*/
|
||||
public static function parseLinkDestination(Cursor $cursor): ?string
|
||||
{
|
||||
if ($res = $cursor->match(RegexHelper::REGEX_LINK_DESTINATION_BRACES)) {
|
||||
// Chop off surrounding <..>:
|
||||
return UrlEncoder::unescapeAndEncode(
|
||||
RegexHelper::unescape(\substr($res, 1, -1))
|
||||
);
|
||||
}
|
||||
|
||||
if ($cursor->getCharacter() === '<') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$destination = self::manuallyParseLinkDestination($cursor);
|
||||
if ($destination === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return UrlEncoder::unescapeAndEncode(
|
||||
RegexHelper::unescape($destination)
|
||||
);
|
||||
}
|
||||
|
||||
public static function parseLinkLabel(Cursor $cursor): int
|
||||
{
|
||||
$match = $cursor->match('/^\[(?:[^\\\\\[\]]|\\\\.){0,1000}\]/');
|
||||
if ($match === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$length = \mb_strlen($match, 'utf-8');
|
||||
|
||||
if ($length > 1001) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to parse link title (sans quotes)
|
||||
*
|
||||
* @param Cursor $cursor
|
||||
*
|
||||
* @return null|string The string, or null if no match
|
||||
*/
|
||||
public static function parseLinkTitle(Cursor $cursor): ?string
|
||||
{
|
||||
if ($title = $cursor->match('/' . RegexHelper::PARTIAL_LINK_TITLE . '/')) {
|
||||
// Chop off quotes from title and unescape
|
||||
return RegexHelper::unescape(\substr($title, 1, -1));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static function manuallyParseLinkDestination(Cursor $cursor): ?string
|
||||
{
|
||||
$oldPosition = $cursor->getPosition();
|
||||
$oldState = $cursor->saveState();
|
||||
|
||||
$openParens = 0;
|
||||
while (($c = $cursor->getCharacter()) !== null) {
|
||||
if ($c === '\\' && $cursor->peek() !== null && RegexHelper::isEscapable($cursor->peek())) {
|
||||
$cursor->advanceBy(2);
|
||||
} elseif ($c === '(') {
|
||||
$cursor->advanceBy(1);
|
||||
$openParens++;
|
||||
} elseif ($c === ')') {
|
||||
if ($openParens < 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
$cursor->advanceBy(1);
|
||||
$openParens--;
|
||||
} elseif (\preg_match(RegexHelper::REGEX_WHITESPACE_CHAR, $c)) {
|
||||
break;
|
||||
} else {
|
||||
$cursor->advanceBy(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ($openParens !== 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($cursor->getPosition() === $oldPosition && $c !== ')') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$newPos = $cursor->getPosition();
|
||||
$cursor->restoreState($oldState);
|
||||
|
||||
$cursor->advanceBy($newPos - $cursor->getPosition());
|
||||
|
||||
return $cursor->getPreviousText();
|
||||
}
|
||||
}
|
||||
71
vendor/league/commonmark/src/Util/PrioritizedList.php
vendored
Normal file
71
vendor/league/commonmark/src/Util/PrioritizedList.php
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Util;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @phpstan-template T
|
||||
* @phpstan-implements \IteratorAggregate<T>
|
||||
*/
|
||||
final class PrioritizedList implements \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* @var array<int, array<mixed>>
|
||||
* @phpstan-var array<int, array<T>>
|
||||
*/
|
||||
private $list = [];
|
||||
|
||||
/**
|
||||
* @var iterable<mixed>|null
|
||||
* @phpstan-var iterable<T>|null
|
||||
*/
|
||||
private $optimized;
|
||||
|
||||
/**
|
||||
* @param mixed $item
|
||||
* @param int $priority
|
||||
*
|
||||
* @phpstan-param T $item
|
||||
*/
|
||||
public function add($item, int $priority): void
|
||||
{
|
||||
$this->list[$priority][] = $item;
|
||||
$this->optimized = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return iterable<int, mixed>
|
||||
*
|
||||
* @phpstan-return iterable<int, T>
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator(): iterable
|
||||
{
|
||||
if ($this->optimized === null) {
|
||||
\krsort($this->list);
|
||||
|
||||
$sorted = [];
|
||||
foreach ($this->list as $group) {
|
||||
foreach ($group as $item) {
|
||||
$sorted[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
$this->optimized = new \ArrayIterator($sorted);
|
||||
}
|
||||
|
||||
return $this->optimized;
|
||||
}
|
||||
}
|
||||
234
vendor/league/commonmark/src/Util/RegexHelper.php
vendored
Normal file
234
vendor/league/commonmark/src/Util/RegexHelper.php
vendored
Normal file
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Util;
|
||||
|
||||
use League\CommonMark\Block\Element\HtmlBlock;
|
||||
|
||||
/**
|
||||
* Provides regular expressions and utilities for parsing Markdown
|
||||
*/
|
||||
final class RegexHelper
|
||||
{
|
||||
// Partial regular expressions (wrap with `/` on each side before use)
|
||||
public const PARTIAL_ENTITY = '&(?:#x[a-f0-9]{1,6}|#[0-9]{1,7}|[a-z][a-z0-9]{1,31});';
|
||||
public const PARTIAL_ESCAPABLE = '[!"#$%&\'()*+,.\/:;<=>?@[\\\\\]^_`{|}~-]';
|
||||
public const PARTIAL_ESCAPED_CHAR = '\\\\' . self::PARTIAL_ESCAPABLE;
|
||||
public const PARTIAL_IN_DOUBLE_QUOTES = '"(' . self::PARTIAL_ESCAPED_CHAR . '|[^"\x00])*"';
|
||||
public const PARTIAL_IN_SINGLE_QUOTES = '\'(' . self::PARTIAL_ESCAPED_CHAR . '|[^\'\x00])*\'';
|
||||
public const PARTIAL_IN_PARENS = '\\((' . self::PARTIAL_ESCAPED_CHAR . '|[^)\x00])*\\)';
|
||||
public const PARTIAL_REG_CHAR = '[^\\\\()\x00-\x20]';
|
||||
public const PARTIAL_IN_PARENS_NOSP = '\((' . self::PARTIAL_REG_CHAR . '|' . self::PARTIAL_ESCAPED_CHAR . '|\\\\)*\)';
|
||||
public const PARTIAL_TAGNAME = '[A-Za-z][A-Za-z0-9-]*';
|
||||
public const PARTIAL_BLOCKTAGNAME = '(?:address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h1|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul)';
|
||||
public const PARTIAL_ATTRIBUTENAME = '[a-zA-Z_:][a-zA-Z0-9:._-]*';
|
||||
public const PARTIAL_UNQUOTEDVALUE = '[^"\'=<>`\x00-\x20]+';
|
||||
public const PARTIAL_SINGLEQUOTEDVALUE = '\'[^\']*\'';
|
||||
public const PARTIAL_DOUBLEQUOTEDVALUE = '"[^"]*"';
|
||||
public const PARTIAL_ATTRIBUTEVALUE = '(?:' . self::PARTIAL_UNQUOTEDVALUE . '|' . self::PARTIAL_SINGLEQUOTEDVALUE . '|' . self::PARTIAL_DOUBLEQUOTEDVALUE . ')';
|
||||
public const PARTIAL_ATTRIBUTEVALUESPEC = '(?:' . '\s*=' . '\s*' . self::PARTIAL_ATTRIBUTEVALUE . ')';
|
||||
public const PARTIAL_ATTRIBUTE = '(?:' . '\s+' . self::PARTIAL_ATTRIBUTENAME . self::PARTIAL_ATTRIBUTEVALUESPEC . '?)';
|
||||
public const PARTIAL_OPENTAG = '<' . self::PARTIAL_TAGNAME . self::PARTIAL_ATTRIBUTE . '*' . '\s*\/?>';
|
||||
public const PARTIAL_CLOSETAG = '<\/' . self::PARTIAL_TAGNAME . '\s*[>]';
|
||||
public const PARTIAL_OPENBLOCKTAG = '<' . self::PARTIAL_BLOCKTAGNAME . self::PARTIAL_ATTRIBUTE . '*' . '\s*\/?>';
|
||||
public const PARTIAL_CLOSEBLOCKTAG = '<\/' . self::PARTIAL_BLOCKTAGNAME . '\s*[>]';
|
||||
public const PARTIAL_HTMLCOMMENT = '<!---->|<!--(?:-?[^>-])(?:-?[^-])*-->';
|
||||
public const PARTIAL_PROCESSINGINSTRUCTION = '[<][?].*?[?][>]';
|
||||
public const PARTIAL_DECLARATION = '<![A-Z]+' . '\s+[^>]*>';
|
||||
public const PARTIAL_CDATA = '<!\[CDATA\[[\s\S]*?]\]>';
|
||||
public const PARTIAL_HTMLTAG = '(?:' . self::PARTIAL_OPENTAG . '|' . self::PARTIAL_CLOSETAG . '|' . self::PARTIAL_HTMLCOMMENT . '|' .
|
||||
self::PARTIAL_PROCESSINGINSTRUCTION . '|' . self::PARTIAL_DECLARATION . '|' . self::PARTIAL_CDATA . ')';
|
||||
public const PARTIAL_HTMLBLOCKOPEN = '<(?:' . self::PARTIAL_BLOCKTAGNAME . '(?:[\s\/>]|$)' . '|' .
|
||||
'\/' . self::PARTIAL_BLOCKTAGNAME . '(?:[\s>]|$)' . '|' . '[?!])';
|
||||
public const PARTIAL_LINK_TITLE = '^(?:"(' . self::PARTIAL_ESCAPED_CHAR . '|[^"\x00])*"' .
|
||||
'|' . '\'(' . self::PARTIAL_ESCAPED_CHAR . '|[^\'\x00])*\'' .
|
||||
'|' . '\((' . self::PARTIAL_ESCAPED_CHAR . '|[^()\x00])*\))';
|
||||
|
||||
public const REGEX_PUNCTUATION = '/^[\x{2000}-\x{206F}\x{2E00}-\x{2E7F}\p{Pc}\p{Pd}\p{Pe}\p{Pf}\p{Pi}\p{Po}\p{Ps}\\\\\'!"#\$%&\(\)\*\+,\-\.\\/:;<=>\?@\[\]\^_`\{\|\}~]/u';
|
||||
public const REGEX_UNSAFE_PROTOCOL = '/^javascript:|vbscript:|file:|data:/i';
|
||||
public const REGEX_SAFE_DATA_PROTOCOL = '/^data:image\/(?:png|gif|jpeg|webp)/i';
|
||||
public const REGEX_NON_SPACE = '/[^ \t\f\v\r\n]/';
|
||||
|
||||
public const REGEX_WHITESPACE_CHAR = '/^[ \t\n\x0b\x0c\x0d]/';
|
||||
public const REGEX_WHITESPACE = '/[ \t\n\x0b\x0c\x0d]+/';
|
||||
public const REGEX_UNICODE_WHITESPACE_CHAR = '/^\pZ|\s/u';
|
||||
public const REGEX_THEMATIC_BREAK = '/^(?:\*[ \t]*){3,}$|^(?:_[ \t]*){3,}$|^(?:-[ \t]*){3,}$/';
|
||||
public const REGEX_LINK_DESTINATION_BRACES = '/^(?:<(?:[^<>\\n\\\\\\x00]|\\\\.)*>)/';
|
||||
|
||||
public static function isEscapable(string $character): bool
|
||||
{
|
||||
return \preg_match('/' . self::PARTIAL_ESCAPABLE . '/', $character) === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to match a regex in string s at offset offset
|
||||
*
|
||||
* @param string $regex
|
||||
* @param string $string
|
||||
* @param int $offset
|
||||
*
|
||||
* @return int|null Index of match, or null
|
||||
*/
|
||||
public static function matchAt(string $regex, string $string, int $offset = 0): ?int
|
||||
{
|
||||
$matches = [];
|
||||
$string = \mb_substr($string, $offset, null, 'utf-8');
|
||||
if (!\preg_match($regex, $string, $matches, \PREG_OFFSET_CAPTURE)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// PREG_OFFSET_CAPTURE always returns the byte offset, not the char offset, which is annoying
|
||||
$charPos = \mb_strlen(\mb_strcut($string, 0, $matches[0][1], 'utf-8'), 'utf-8');
|
||||
|
||||
return $offset + $charPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Functional wrapper around preg_match_all
|
||||
*
|
||||
* @param string $pattern
|
||||
* @param string $subject
|
||||
* @param int $offset
|
||||
*
|
||||
* @return array<string>|null
|
||||
*
|
||||
* @deprecated in 1.6; use matchFirst() instead
|
||||
*/
|
||||
public static function matchAll(string $pattern, string $subject, int $offset = 0): ?array
|
||||
{
|
||||
@\trigger_error('RegexHelper::matchAll() is deprecated in league/commonmark 1.6 and will be removed in 2.0; use RegexHelper::matchFirst() instead', \E_USER_DEPRECATED);
|
||||
|
||||
if ($offset !== 0) {
|
||||
$subject = \substr($subject, $offset);
|
||||
}
|
||||
|
||||
\preg_match_all($pattern, $subject, $matches, \PREG_PATTERN_ORDER);
|
||||
|
||||
$fullMatches = \reset($matches);
|
||||
if (empty($fullMatches)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (\count($fullMatches) === 1) {
|
||||
foreach ($matches as &$match) {
|
||||
$match = \reset($match);
|
||||
}
|
||||
}
|
||||
|
||||
return $matches ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Functional wrapper around preg_match_all which only returns the first set of matches
|
||||
*
|
||||
* @return string[]|null
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function matchFirst(string $pattern, string $subject, int $offset = 0): ?array
|
||||
{
|
||||
if ($offset !== 0) {
|
||||
$subject = \substr($subject, $offset);
|
||||
}
|
||||
|
||||
\preg_match_all($pattern, $subject, $matches, \PREG_SET_ORDER);
|
||||
|
||||
if ($matches === []) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $matches[0] ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace backslash escapes with literal characters
|
||||
*
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function unescape(string $string): string
|
||||
{
|
||||
$allEscapedChar = '/\\\\(' . self::PARTIAL_ESCAPABLE . ')/';
|
||||
|
||||
/** @var string $escaped */
|
||||
$escaped = \preg_replace($allEscapedChar, '$1', $string);
|
||||
|
||||
/** @var string $replaced */
|
||||
$replaced = \preg_replace_callback('/' . self::PARTIAL_ENTITY . '/i', function ($e) {
|
||||
return Html5EntityDecoder::decode($e[0]);
|
||||
}, $escaped);
|
||||
|
||||
return $replaced;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $type HTML block type
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function getHtmlBlockOpenRegex(int $type): string
|
||||
{
|
||||
switch ($type) {
|
||||
case HtmlBlock::TYPE_1_CODE_CONTAINER:
|
||||
return '/^<(?:script|pre|textarea|style)(?:\s|>|$)/i';
|
||||
case HtmlBlock::TYPE_2_COMMENT:
|
||||
return '/^<!--/';
|
||||
case HtmlBlock::TYPE_3:
|
||||
return '/^<[?]/';
|
||||
case HtmlBlock::TYPE_4:
|
||||
return '/^<![A-Z]/';
|
||||
case HtmlBlock::TYPE_5_CDATA:
|
||||
return '/^<!\[CDATA\[/';
|
||||
case HtmlBlock::TYPE_6_BLOCK_ELEMENT:
|
||||
return '%^<[/]?(?:address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[123456]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul)(?:\s|[/]?[>]|$)%i';
|
||||
case HtmlBlock::TYPE_7_MISC_ELEMENT:
|
||||
return '/^(?:' . self::PARTIAL_OPENTAG . '|' . self::PARTIAL_CLOSETAG . ')\\s*$/i';
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException('Invalid HTML block type');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $type HTML block type
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function getHtmlBlockCloseRegex(int $type): string
|
||||
{
|
||||
switch ($type) {
|
||||
case HtmlBlock::TYPE_1_CODE_CONTAINER:
|
||||
return '%<\/(?:script|pre|textarea|style)>%i';
|
||||
case HtmlBlock::TYPE_2_COMMENT:
|
||||
return '/-->/';
|
||||
case HtmlBlock::TYPE_3:
|
||||
return '/\?>/';
|
||||
case HtmlBlock::TYPE_4:
|
||||
return '/>/';
|
||||
case HtmlBlock::TYPE_5_CDATA:
|
||||
return '/\]\]>/';
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException('Invalid HTML block type');
|
||||
}
|
||||
|
||||
public static function isLinkPotentiallyUnsafe(string $url): bool
|
||||
{
|
||||
return \preg_match(self::REGEX_UNSAFE_PROTOCOL, $url) !== 0 && \preg_match(self::REGEX_SAFE_DATA_PROTOCOL, $url) === 0;
|
||||
}
|
||||
}
|
||||
60
vendor/league/commonmark/src/Util/UrlEncoder.php
vendored
Normal file
60
vendor/league/commonmark/src/Util/UrlEncoder.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Util;
|
||||
|
||||
use League\CommonMark\Exception\UnexpectedEncodingException;
|
||||
|
||||
final class UrlEncoder
|
||||
{
|
||||
/** @var string[] */
|
||||
private static $encodeCache = ['%00', '%01', '%02', '%03', '%04', '%05', '%06', '%07', '%08', '%09', '%0A', '%0B', '%0C', '%0D', '%0E', '%0F', '%10', '%11', '%12', '%13', '%14', '%15', '%16', '%17', '%18', '%19', '%1A', '%1B', '%1C', '%1D', '%1E', '%1F', '%20', '!', '%22', '#', '$', '%25', '&', "'", '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '%3C', '=', '%3E', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '%5B', '%5C', '%5D', '%5E', '_', '%60', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '%7B', '%7C', '%7D', '~', '%7F'];
|
||||
|
||||
public static function unescapeAndEncode(string $uri): string
|
||||
{
|
||||
// Optimization: if the URL only includes characters we know will be kept as-is, then just return the URL as-is.
|
||||
if (\preg_match('/^[A-Za-z0-9~!@#$&*()\-_=+;:,.\/?]+$/', $uri)) {
|
||||
return $uri;
|
||||
}
|
||||
|
||||
$result = '';
|
||||
|
||||
$chars = \preg_split('//u', $uri, -1, \PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
if (!\is_array($chars) || !\mb_check_encoding($uri, 'UTF-8')) {
|
||||
throw new UnexpectedEncodingException('Unexpected encoding - UTF-8 or ASCII was expected');
|
||||
}
|
||||
|
||||
$l = \count($chars);
|
||||
for ($i = 0; $i < $l; $i++) {
|
||||
$code = $chars[$i];
|
||||
if ($code === '%' && $i + 2 < $l) {
|
||||
if (\preg_match('/^[0-9a-f]{2}$/i', $chars[$i + 1] . $chars[$i + 2]) === 1) {
|
||||
$result .= '%' . $chars[$i + 1] . $chars[$i + 2];
|
||||
$i += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (\ord($code) < 128) {
|
||||
$result .= self::$encodeCache[\ord($code)];
|
||||
continue;
|
||||
}
|
||||
|
||||
$result .= \rawurlencode($code);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
31
vendor/league/commonmark/src/Util/Xml.php
vendored
Normal file
31
vendor/league/commonmark/src/Util/Xml.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Util;
|
||||
|
||||
/**
|
||||
* Utility class for handling/generating XML and HTML
|
||||
*/
|
||||
final class Xml
|
||||
{
|
||||
/**
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function escape($string)
|
||||
{
|
||||
return \str_replace(['&', '<', '>', '"'], ['&', '<', '>', '"'], $string);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user