Commaaa2
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
@@ -14,58 +16,50 @@
|
||||
|
||||
namespace League\CommonMark\Delimiter;
|
||||
|
||||
use League\CommonMark\Inline\Element\AbstractStringContainer;
|
||||
use League\CommonMark\Node\Inline\AbstractStringContainer;
|
||||
|
||||
final class Delimiter implements DelimiterInterface
|
||||
{
|
||||
/** @var string */
|
||||
private $char;
|
||||
/** @psalm-readonly */
|
||||
private string $char;
|
||||
|
||||
/** @var int */
|
||||
private $length;
|
||||
/** @psalm-readonly-allow-private-mutation */
|
||||
private int $length;
|
||||
|
||||
/** @var int */
|
||||
private $originalLength;
|
||||
/** @psalm-readonly */
|
||||
private int $originalLength;
|
||||
|
||||
/** @var AbstractStringContainer */
|
||||
private $inlineNode;
|
||||
/** @psalm-readonly */
|
||||
private AbstractStringContainer $inlineNode;
|
||||
|
||||
/** @var DelimiterInterface|null */
|
||||
private $previous;
|
||||
/** @psalm-readonly-allow-private-mutation */
|
||||
private ?DelimiterInterface $previous = null;
|
||||
|
||||
/** @var DelimiterInterface|null */
|
||||
private $next;
|
||||
/** @psalm-readonly-allow-private-mutation */
|
||||
private ?DelimiterInterface $next = null;
|
||||
|
||||
/** @var bool */
|
||||
private $canOpen;
|
||||
/** @psalm-readonly */
|
||||
private bool $canOpen;
|
||||
|
||||
/** @var bool */
|
||||
private $canClose;
|
||||
/** @psalm-readonly */
|
||||
private bool $canClose;
|
||||
|
||||
/** @var bool */
|
||||
private $active;
|
||||
/** @psalm-readonly-allow-private-mutation */
|
||||
private bool $active;
|
||||
|
||||
/** @var int|null */
|
||||
private $index;
|
||||
/** @psalm-readonly */
|
||||
private ?int $index = null;
|
||||
|
||||
/**
|
||||
* @param string $char
|
||||
* @param int $numDelims
|
||||
* @param AbstractStringContainer $node
|
||||
* @param bool $canOpen
|
||||
* @param bool $canClose
|
||||
* @param int|null $index
|
||||
*/
|
||||
public function __construct(string $char, int $numDelims, AbstractStringContainer $node, bool $canOpen, bool $canClose, ?int $index = null)
|
||||
{
|
||||
$this->char = $char;
|
||||
$this->length = $numDelims;
|
||||
$this->char = $char;
|
||||
$this->length = $numDelims;
|
||||
$this->originalLength = $numDelims;
|
||||
$this->inlineNode = $node;
|
||||
$this->canOpen = $canOpen;
|
||||
$this->canClose = $canClose;
|
||||
$this->active = true;
|
||||
$this->index = $index;
|
||||
$this->inlineNode = $node;
|
||||
$this->canOpen = $canOpen;
|
||||
$this->canClose = $canClose;
|
||||
$this->active = true;
|
||||
$this->index = $index;
|
||||
}
|
||||
|
||||
public function canClose(): bool
|
||||
@@ -73,16 +67,6 @@ final class Delimiter implements DelimiterInterface
|
||||
return $this->canClose;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $canClose
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setCanClose(bool $canClose)
|
||||
{
|
||||
$this->canClose = $canClose;
|
||||
}
|
||||
|
||||
public function canOpen(): bool
|
||||
{
|
||||
return $this->canOpen;
|
||||
@@ -93,7 +77,7 @@ final class Delimiter implements DelimiterInterface
|
||||
return $this->active;
|
||||
}
|
||||
|
||||
public function setActive(bool $active)
|
||||
public function setActive(bool $active): void
|
||||
{
|
||||
$this->active = $active;
|
||||
}
|
||||
@@ -113,7 +97,7 @@ final class Delimiter implements DelimiterInterface
|
||||
return $this->next;
|
||||
}
|
||||
|
||||
public function setNext(?DelimiterInterface $next)
|
||||
public function setNext(?DelimiterInterface $next): void
|
||||
{
|
||||
$this->next = $next;
|
||||
}
|
||||
@@ -123,7 +107,7 @@ final class Delimiter implements DelimiterInterface
|
||||
return $this->length;
|
||||
}
|
||||
|
||||
public function setLength(int $length)
|
||||
public function setLength(int $length): void
|
||||
{
|
||||
$this->length = $length;
|
||||
}
|
||||
@@ -143,10 +127,8 @@ final class Delimiter implements DelimiterInterface
|
||||
return $this->previous;
|
||||
}
|
||||
|
||||
public function setPrevious(?DelimiterInterface $previous): DelimiterInterface
|
||||
public function setPrevious(?DelimiterInterface $previous): void
|
||||
{
|
||||
$this->previous = $previous;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
@@ -14,7 +16,7 @@
|
||||
|
||||
namespace League\CommonMark\Delimiter;
|
||||
|
||||
use League\CommonMark\Inline\Element\AbstractStringContainer;
|
||||
use League\CommonMark\Node\Inline\AbstractStringContainer;
|
||||
|
||||
interface DelimiterInterface
|
||||
{
|
||||
@@ -24,37 +26,19 @@ interface DelimiterInterface
|
||||
|
||||
public function isActive(): bool;
|
||||
|
||||
/**
|
||||
* @param bool $active
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setActive(bool $active);
|
||||
public function setActive(bool $active): void;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getChar(): string;
|
||||
|
||||
public function getIndex(): ?int;
|
||||
|
||||
public function getNext(): ?DelimiterInterface;
|
||||
|
||||
/**
|
||||
* @param DelimiterInterface|null $next
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setNext(?DelimiterInterface $next);
|
||||
public function setNext(?DelimiterInterface $next): void;
|
||||
|
||||
public function getLength(): int;
|
||||
|
||||
/**
|
||||
* @param int $length
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setLength(int $length);
|
||||
public function setLength(int $length): void;
|
||||
|
||||
public function getOriginalLength(): int;
|
||||
|
||||
@@ -62,10 +46,5 @@ interface DelimiterInterface
|
||||
|
||||
public function getPrevious(): ?DelimiterInterface;
|
||||
|
||||
/**
|
||||
* @param DelimiterInterface|null $previous
|
||||
*
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function setPrevious(?DelimiterInterface $previous);
|
||||
public function setPrevious(?DelimiterInterface $previous): void;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
@@ -18,21 +20,14 @@
|
||||
namespace League\CommonMark\Delimiter;
|
||||
|
||||
use League\CommonMark\Delimiter\Processor\DelimiterProcessorCollection;
|
||||
use League\CommonMark\Inline\AdjacentTextMerger;
|
||||
use League\CommonMark\Node\Inline\AdjacentTextMerger;
|
||||
|
||||
final class DelimiterStack
|
||||
{
|
||||
/**
|
||||
* @var DelimiterInterface|null
|
||||
*/
|
||||
private $top;
|
||||
/** @psalm-readonly-allow-private-mutation */
|
||||
private ?DelimiterInterface $top = null;
|
||||
|
||||
/**
|
||||
* @param DelimiterInterface $newDelimiter
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function push(DelimiterInterface $newDelimiter)
|
||||
public function push(DelimiterInterface $newDelimiter): void
|
||||
{
|
||||
$newDelimiter->setPrevious($this->top);
|
||||
|
||||
@@ -43,7 +38,7 @@ final class DelimiterStack
|
||||
$this->top = $newDelimiter;
|
||||
}
|
||||
|
||||
private function findEarliest(DelimiterInterface $stackBottom = null): ?DelimiterInterface
|
||||
private function findEarliest(?DelimiterInterface $stackBottom = null): ?DelimiterInterface
|
||||
{
|
||||
$delimiter = $this->top;
|
||||
while ($delimiter !== null && $delimiter->getPrevious() !== $stackBottom) {
|
||||
@@ -53,14 +48,10 @@ final class DelimiterStack
|
||||
return $delimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DelimiterInterface $delimiter
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function removeDelimiter(DelimiterInterface $delimiter)
|
||||
public function removeDelimiter(DelimiterInterface $delimiter): void
|
||||
{
|
||||
if ($delimiter->getPrevious() !== null) {
|
||||
/** @psalm-suppress PossiblyNullReference */
|
||||
$delimiter->getPrevious()->setNext($delimiter->getNext());
|
||||
}
|
||||
|
||||
@@ -68,6 +59,7 @@ final class DelimiterStack
|
||||
// top of stack
|
||||
$this->top = $delimiter->getPrevious();
|
||||
} else {
|
||||
/** @psalm-suppress PossiblyNullReference */
|
||||
$delimiter->getNext()->setPrevious($delimiter->getPrevious());
|
||||
}
|
||||
}
|
||||
@@ -88,24 +80,14 @@ final class DelimiterStack
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DelimiterInterface|null $stackBottom
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function removeAll(DelimiterInterface $stackBottom = null)
|
||||
public function removeAll(?DelimiterInterface $stackBottom = null): void
|
||||
{
|
||||
while ($this->top && $this->top !== $stackBottom) {
|
||||
$this->removeDelimiter($this->top);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $character
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function removeEarlierMatches(string $character)
|
||||
public function removeEarlierMatches(string $character): void
|
||||
{
|
||||
$opener = $this->top;
|
||||
while ($opener !== null) {
|
||||
@@ -119,33 +101,26 @@ final class DelimiterStack
|
||||
|
||||
/**
|
||||
* @param string|string[] $characters
|
||||
*
|
||||
* @return DelimiterInterface|null
|
||||
*/
|
||||
public function searchByCharacter($characters): ?DelimiterInterface
|
||||
{
|
||||
if (!\is_array($characters)) {
|
||||
if (! \is_array($characters)) {
|
||||
$characters = [$characters];
|
||||
}
|
||||
|
||||
$opener = $this->top;
|
||||
while ($opener !== null) {
|
||||
if (\in_array($opener->getChar(), $characters)) {
|
||||
if (\in_array($opener->getChar(), $characters, true)) {
|
||||
break;
|
||||
}
|
||||
|
||||
$opener = $opener->getPrevious();
|
||||
}
|
||||
|
||||
return $opener;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DelimiterInterface|null $stackBottom
|
||||
* @param DelimiterProcessorCollection $processors
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function processDelimiters(?DelimiterInterface $stackBottom, DelimiterProcessorCollection $processors)
|
||||
public function processDelimiters(?DelimiterInterface $stackBottom, DelimiterProcessorCollection $processors): void
|
||||
{
|
||||
$openersBottom = [];
|
||||
|
||||
@@ -157,31 +132,32 @@ final class DelimiterStack
|
||||
$delimiterChar = $closer->getChar();
|
||||
|
||||
$delimiterProcessor = $processors->getDelimiterProcessor($delimiterChar);
|
||||
if (!$closer->canClose() || $delimiterProcessor === null) {
|
||||
if (! $closer->canClose() || $delimiterProcessor === null) {
|
||||
$closer = $closer->getNext();
|
||||
continue;
|
||||
}
|
||||
|
||||
$openingDelimiterChar = $delimiterProcessor->getOpeningCharacter();
|
||||
|
||||
$useDelims = 0;
|
||||
$openerFound = false;
|
||||
$useDelims = 0;
|
||||
$openerFound = false;
|
||||
$potentialOpenerFound = false;
|
||||
$opener = $closer->getPrevious();
|
||||
$opener = $closer->getPrevious();
|
||||
while ($opener !== null && $opener !== $stackBottom && $opener !== ($openersBottom[$delimiterChar] ?? null)) {
|
||||
if ($opener->canOpen() && $opener->getChar() === $openingDelimiterChar) {
|
||||
$potentialOpenerFound = true;
|
||||
$useDelims = $delimiterProcessor->getDelimiterUse($opener, $closer);
|
||||
$useDelims = $delimiterProcessor->getDelimiterUse($opener, $closer);
|
||||
if ($useDelims > 0) {
|
||||
$openerFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$opener = $opener->getPrevious();
|
||||
}
|
||||
|
||||
if (!$openerFound) {
|
||||
if (!$potentialOpenerFound) {
|
||||
if (! $openerFound) {
|
||||
if (! $potentialOpenerFound) {
|
||||
// Only do this when we didn't even have a potential
|
||||
// opener (one that matches the character and can open).
|
||||
// If an opener was rejected because of the number of
|
||||
@@ -190,16 +166,19 @@ final class DelimiterStack
|
||||
// we want to consider it next time because the number
|
||||
// of delimiters can change as we continue processing.
|
||||
$openersBottom[$delimiterChar] = $closer->getPrevious();
|
||||
if (!$closer->canOpen()) {
|
||||
if (! $closer->canOpen()) {
|
||||
// We can remove a closer that can't be an opener,
|
||||
// once we've seen there's no matching opener.
|
||||
$this->removeDelimiter($closer);
|
||||
}
|
||||
}
|
||||
|
||||
$closer = $closer->getNext();
|
||||
continue;
|
||||
}
|
||||
|
||||
\assert($opener !== null);
|
||||
|
||||
$openerNode = $opener->getInlineNode();
|
||||
$closerNode = $closer->getInlineNode();
|
||||
|
||||
@@ -207,8 +186,8 @@ final class DelimiterStack
|
||||
$opener->setLength($opener->getLength() - $useDelims);
|
||||
$closer->setLength($closer->getLength() - $useDelims);
|
||||
|
||||
$openerNode->setContent(\substr($openerNode->getContent(), 0, -$useDelims));
|
||||
$closerNode->setContent(\substr($closerNode->getContent(), 0, -$useDelims));
|
||||
$openerNode->setLiteral(\substr($openerNode->getLiteral(), 0, -$useDelims));
|
||||
$closerNode->setLiteral(\substr($closerNode->getLiteral(), 0, -$useDelims));
|
||||
|
||||
$this->removeDelimitersBetween($opener, $closer);
|
||||
// The delimiter processor can re-parent the nodes between opener and closer,
|
||||
@@ -221,6 +200,7 @@ final class DelimiterStack
|
||||
$this->removeDelimiterAndNode($opener);
|
||||
}
|
||||
|
||||
// phpcs:disable SlevomatCodingStandard.ControlStructures.EarlyExit.EarlyExitNotUsed
|
||||
if ($closer->getLength() === 0) {
|
||||
$next = $closer->getNext();
|
||||
$this->removeDelimiterAndNode($closer);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
@@ -17,12 +19,18 @@
|
||||
|
||||
namespace League\CommonMark\Delimiter\Processor;
|
||||
|
||||
use League\CommonMark\Exception\InvalidArgumentException;
|
||||
|
||||
final class DelimiterProcessorCollection implements DelimiterProcessorCollectionInterface
|
||||
{
|
||||
/** @var array<string,DelimiterProcessorInterface>|DelimiterProcessorInterface[] */
|
||||
private $processorsByChar = [];
|
||||
/**
|
||||
* @var array<string,DelimiterProcessorInterface>|DelimiterProcessorInterface[]
|
||||
*
|
||||
* @psalm-readonly-allow-private-mutation
|
||||
*/
|
||||
private array $processorsByChar = [];
|
||||
|
||||
public function add(DelimiterProcessorInterface $processor)
|
||||
public function add(DelimiterProcessorInterface $processor): void
|
||||
{
|
||||
$opening = $processor->getOpeningCharacter();
|
||||
$closing = $processor->getClosingCharacter();
|
||||
@@ -45,6 +53,9 @@ final class DelimiterProcessorCollection implements DelimiterProcessorCollection
|
||||
return $this->processorsByChar[$char] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getDelimiterCharacters(): array
|
||||
{
|
||||
return \array_keys($this->processorsByChar);
|
||||
@@ -53,7 +64,7 @@ final class DelimiterProcessorCollection implements DelimiterProcessorCollection
|
||||
private function addDelimiterProcessorForChar(string $delimiterChar, DelimiterProcessorInterface $processor): void
|
||||
{
|
||||
if (isset($this->processorsByChar[$delimiterChar])) {
|
||||
throw new \InvalidArgumentException(\sprintf('Delim processor for character "%s" already exists', $processor->getOpeningCharacter()));
|
||||
throw new InvalidArgumentException(\sprintf('Delim processor for character "%s" already exists', $processor->getOpeningCharacter()));
|
||||
}
|
||||
|
||||
$this->processorsByChar[$delimiterChar] = $processor;
|
||||
@@ -70,4 +81,9 @@ final class DelimiterProcessorCollection implements DelimiterProcessorCollection
|
||||
$s->add($new);
|
||||
$this->processorsByChar[$opening] = $s;
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return \count($this->processorsByChar);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
@@ -17,25 +19,21 @@
|
||||
|
||||
namespace League\CommonMark\Delimiter\Processor;
|
||||
|
||||
interface DelimiterProcessorCollectionInterface
|
||||
use League\CommonMark\Exception\InvalidArgumentException;
|
||||
|
||||
interface DelimiterProcessorCollectionInterface extends \Countable
|
||||
{
|
||||
/**
|
||||
* Add the given delim processor to the collection
|
||||
*
|
||||
* @param DelimiterProcessorInterface $processor The delim processor to add
|
||||
*
|
||||
* @throws \InvalidArgumentException Exception will be thrown if attempting to add multiple processors for the same character
|
||||
*
|
||||
* @return void
|
||||
* @throws InvalidArgumentException Exception will be thrown if attempting to add multiple processors for the same character
|
||||
*/
|
||||
public function add(DelimiterProcessorInterface $processor);
|
||||
public function add(DelimiterProcessorInterface $processor): void;
|
||||
|
||||
/**
|
||||
* Returns the delim processor which handles the given character if one exists
|
||||
*
|
||||
* @param string $char
|
||||
*
|
||||
* @return DelimiterProcessorInterface|null
|
||||
*/
|
||||
public function getDelimiterProcessor(string $char): ?DelimiterProcessorInterface;
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
@@ -18,7 +20,7 @@
|
||||
namespace League\CommonMark\Delimiter\Processor;
|
||||
|
||||
use League\CommonMark\Delimiter\DelimiterInterface;
|
||||
use League\CommonMark\Inline\Element\AbstractStringContainer;
|
||||
use League\CommonMark\Node\Inline\AbstractStringContainer;
|
||||
|
||||
/**
|
||||
* Interface for a delimiter processor
|
||||
@@ -29,8 +31,6 @@ interface DelimiterProcessorInterface
|
||||
* Returns the character that marks the beginning of a delimited node.
|
||||
*
|
||||
* This must not clash with any other processors being added to the environment.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOpeningCharacter(): string;
|
||||
|
||||
@@ -40,8 +40,6 @@ interface DelimiterProcessorInterface
|
||||
* This must not clash with any other processors being added to the environment.
|
||||
*
|
||||
* Note that for a symmetric delimiter such as "*", this is the same as the opening.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getClosingCharacter(): string;
|
||||
|
||||
@@ -49,8 +47,6 @@ interface DelimiterProcessorInterface
|
||||
* Minimum number of delimiter characters that are needed to active this.
|
||||
*
|
||||
* Must be at least 1.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getMinLength(): int;
|
||||
|
||||
@@ -64,8 +60,6 @@ interface DelimiterProcessorInterface
|
||||
*
|
||||
* @param DelimiterInterface $opener The opening delimiter run
|
||||
* @param DelimiterInterface $closer The closing delimiter run
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getDelimiterUse(DelimiterInterface $opener, DelimiterInterface $closer): int;
|
||||
|
||||
@@ -79,8 +73,6 @@ interface DelimiterProcessorInterface
|
||||
* @param AbstractStringContainer $opener The node that contained the opening delimiter
|
||||
* @param AbstractStringContainer $closer The node that contained the closing delimiter
|
||||
* @param int $delimiterUse The number of delimiters that were used
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(AbstractStringContainer $opener, AbstractStringContainer $closer, int $delimiterUse);
|
||||
public function process(AbstractStringContainer $opener, AbstractStringContainer $closer, int $delimiterUse): void;
|
||||
}
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* Additional emphasis processing code based on commonmark-java (https://github.com/atlassian/commonmark-java)
|
||||
* - (c) Atlassian Pty Ltd
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Delimiter\Processor;
|
||||
|
||||
use League\CommonMark\Delimiter\DelimiterInterface;
|
||||
use League\CommonMark\Inline\Element\AbstractStringContainer;
|
||||
use League\CommonMark\Inline\Element\Emphasis;
|
||||
use League\CommonMark\Inline\Element\Strong;
|
||||
use League\CommonMark\Util\ConfigurationAwareInterface;
|
||||
use League\CommonMark\Util\ConfigurationInterface;
|
||||
|
||||
final class EmphasisDelimiterProcessor implements DelimiterProcessorInterface, ConfigurationAwareInterface
|
||||
{
|
||||
/** @var string */
|
||||
private $char;
|
||||
|
||||
/** @var ConfigurationInterface|null */
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @param string $char The emphasis character to use (typically '*' or '_')
|
||||
*/
|
||||
public function __construct(string $char)
|
||||
{
|
||||
$this->char = $char;
|
||||
}
|
||||
|
||||
public function getOpeningCharacter(): string
|
||||
{
|
||||
return $this->char;
|
||||
}
|
||||
|
||||
public function getClosingCharacter(): string
|
||||
{
|
||||
return $this->char;
|
||||
}
|
||||
|
||||
public function getMinLength(): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function getDelimiterUse(DelimiterInterface $opener, DelimiterInterface $closer): int
|
||||
{
|
||||
// "Multiple of 3" rule for internal delimiter runs
|
||||
if (($opener->canClose() || $closer->canOpen()) && $closer->getOriginalLength() % 3 !== 0 && ($opener->getOriginalLength() + $closer->getOriginalLength()) % 3 === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate actual number of delimiters used from this closer
|
||||
if ($opener->getLength() >= 2 && $closer->getLength() >= 2) {
|
||||
if ($this->enableStrong()) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($this->enableEm()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function process(AbstractStringContainer $opener, AbstractStringContainer $closer, int $delimiterUse)
|
||||
{
|
||||
if ($delimiterUse === 1) {
|
||||
$emphasis = new Emphasis();
|
||||
} elseif ($delimiterUse === 2) {
|
||||
$emphasis = new Strong();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
$next = $opener->next();
|
||||
while ($next !== null && $next !== $closer) {
|
||||
$tmp = $next->next();
|
||||
$emphasis->appendChild($next);
|
||||
$next = $tmp;
|
||||
}
|
||||
|
||||
$opener->insertAfter($emphasis);
|
||||
}
|
||||
|
||||
public function setConfiguration(ConfigurationInterface $configuration)
|
||||
{
|
||||
$this->config = $configuration;
|
||||
}
|
||||
|
||||
private function enableStrong(): bool
|
||||
{
|
||||
if ($this->config === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$deprecatedEnableStrong = $this->config->get('enable_strong', ConfigurationInterface::MISSING);
|
||||
if ($deprecatedEnableStrong !== ConfigurationInterface::MISSING) {
|
||||
@\trigger_error('The "enable_strong" configuration option is deprecated in league/commonmark 1.6 and will be replaced with "commonmark > enable_strong" in 2.0', \E_USER_DEPRECATED);
|
||||
} else {
|
||||
$deprecatedEnableStrong = true;
|
||||
}
|
||||
|
||||
return $this->config->get('commonmark/enable_strong', $deprecatedEnableStrong);
|
||||
}
|
||||
|
||||
private function enableEm(): bool
|
||||
{
|
||||
if ($this->config === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$deprecatedEnableEm = $this->config->get('enable_em', ConfigurationInterface::MISSING);
|
||||
if ($deprecatedEnableEm !== ConfigurationInterface::MISSING) {
|
||||
@\trigger_error('The "enable_em" configuration option is deprecated in league/commonmark 1.6 and will be replaced with "commonmark > enable_em" in 2.0', \E_USER_DEPRECATED);
|
||||
} else {
|
||||
$deprecatedEnableEm = true;
|
||||
}
|
||||
|
||||
return $this->config->get('commonmark/enable_em', $deprecatedEnableEm);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
@@ -15,7 +17,8 @@
|
||||
namespace League\CommonMark\Delimiter\Processor;
|
||||
|
||||
use League\CommonMark\Delimiter\DelimiterInterface;
|
||||
use League\CommonMark\Inline\Element\AbstractStringContainer;
|
||||
use League\CommonMark\Exception\InvalidArgumentException;
|
||||
use League\CommonMark\Node\Inline\AbstractStringContainer;
|
||||
|
||||
/**
|
||||
* An implementation of DelimiterProcessorInterface that dispatches all calls to two or more other DelimiterProcessors
|
||||
@@ -27,14 +30,18 @@ use League\CommonMark\Inline\Element\AbstractStringContainer;
|
||||
*/
|
||||
final class StaggeredDelimiterProcessor implements DelimiterProcessorInterface
|
||||
{
|
||||
/** @var string */
|
||||
private $delimiterChar;
|
||||
/** @psalm-readonly */
|
||||
private string $delimiterChar;
|
||||
|
||||
/** @var int */
|
||||
private $minLength = 0;
|
||||
/** @psalm-readonly-allow-private-mutation */
|
||||
private int $minLength = 0;
|
||||
|
||||
/** @var array<int, DelimiterProcessorInterface>|DelimiterProcessorInterface[] */
|
||||
private $processors = []; // keyed by minLength in reverse order
|
||||
/**
|
||||
* @var array<int, DelimiterProcessorInterface>|DelimiterProcessorInterface[]
|
||||
*
|
||||
* @psalm-readonly-allow-private-mutation
|
||||
*/
|
||||
private array $processors = []; // keyed by minLength in reverse order
|
||||
|
||||
public function __construct(string $char, DelimiterProcessorInterface $processor)
|
||||
{
|
||||
@@ -60,16 +67,14 @@ final class StaggeredDelimiterProcessor implements DelimiterProcessorInterface
|
||||
/**
|
||||
* Adds the given processor to this staggered delimiter processor
|
||||
*
|
||||
* @param DelimiterProcessorInterface $processor
|
||||
*
|
||||
* @return void
|
||||
* @throws InvalidArgumentException if attempting to add another processors for the same character and minimum length
|
||||
*/
|
||||
public function add(DelimiterProcessorInterface $processor)
|
||||
public function add(DelimiterProcessorInterface $processor): void
|
||||
{
|
||||
$len = $processor->getMinLength();
|
||||
|
||||
if (isset($this->processors[$len])) {
|
||||
throw new \InvalidArgumentException(\sprintf('Cannot add two delimiter processors for char "%s" and minimum length %d', $this->delimiterChar, $len));
|
||||
throw new InvalidArgumentException(\sprintf('Cannot add two delimiter processors for char "%s" and minimum length %d', $this->delimiterChar, $len));
|
||||
}
|
||||
|
||||
$this->processors[$len] = $processor;
|
||||
@@ -83,7 +88,7 @@ final class StaggeredDelimiterProcessor implements DelimiterProcessorInterface
|
||||
return $this->findProcessor($opener->getLength())->getDelimiterUse($opener, $closer);
|
||||
}
|
||||
|
||||
public function process(AbstractStringContainer $opener, AbstractStringContainer $closer, int $delimiterUse)
|
||||
public function process(AbstractStringContainer $opener, AbstractStringContainer $closer, int $delimiterUse): void
|
||||
{
|
||||
$this->findProcessor($delimiterUse)->process($opener, $closer, $delimiterUse);
|
||||
}
|
||||
@@ -98,8 +103,8 @@ final class StaggeredDelimiterProcessor implements DelimiterProcessorInterface
|
||||
}
|
||||
|
||||
// Just use the first one in our list
|
||||
/** @var DelimiterProcessorInterface $first */
|
||||
$first = \reset($this->processors);
|
||||
\assert($first instanceof DelimiterProcessorInterface);
|
||||
|
||||
return $first;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user