/**
* @param ContextInterface $context
* @param InlineParserContext $inlineContext
*
* @return bool
*/
public function parse(ContextInterface $context, InlineParserContext $inlineContext)
{
$cursor = $inlineContext->getCursor();
$startPos = $cursor->getPosition();
$previousState = $cursor->saveState();
// 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;
}
$isImage = $opener->getChar() === '!';
// Instead of copying a slice, we null out the parts of inlines that don't correspond to linkText; later, we'll
// collapse them. This is awkward, and could be simplified if we made inlines a linked list instead
$inlines = $inlineContext->getInlines();
$labelInlines = new ArrayCollection($inlines->toArray());
$this->nullify($labelInlines, 0, $opener->getPos() + 1);
$cursor->advance();
// Check to see if we have a link/image
if (!($link = $this->tryParseLink($cursor, $context->getDocument()->getReferenceMap(), $opener, $startPos))) {
// No match
$inlineContext->getDelimiterStack()->removeDelimiter($opener);
// Remove this opener from stack
$cursor->restoreState($previousState);
return false;
}
$delimiterStack = $inlineContext->getDelimiterStack();
$stackBottom = $opener->getPrevious();
foreach ($this->environment->getInlineProcessors() as $inlineProcessor) {
$inlineProcessor->processInlines($labelInlines, $delimiterStack, $stackBottom);
}
if ($delimiterStack instanceof DelimiterStack) {
$delimiterStack->removeAll($stackBottom);
}
// Remove the part of inlines that become link_text
$this->nullify($inlines, $opener->getPos(), $inlines->count());
// 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('[');
}
$inlines->add($this->createInline($link['url'], $labelInlines, $link['title'], $isImage));
return true;
}