/** * @param \League\CommonMark\ContextInterface $context * @param \League\CommonMark\InlineParserContext $inlineContext * @return bool */ public function parse(ContextInterface $context, InlineParserContext $inlineContext) { $this->context = $context; $this->inlineContext = $inlineContext; $this->cursor = $inlineContext->getCursor(); $this->originalState = $this->cursor->saveState(); $this->cursor->advance(); return $this->parseMediaType(); }
public function parse(ContextInterface $context, Cursor $cursor) { $document = $context->getDocument(); $tip = $context->getTip(); if (!$document->getLastChild() instanceof AttributesDocument) { $attributesDocument = new AttributesDocument(); foreach ($document->getChildren() as $child) { $document->removeChild($child); $attributesDocument->addChild($child); } $document->addChild($attributesDocument); if ($tip instanceof Document) { $context->setTip($attributesDocument); } } $state = $cursor->saveState(); $attributes = AttributesUtils::parse($cursor); if (empty($attributes)) { return false; } if (null !== $cursor->getFirstNonSpaceCharacter()) { $cursor->restoreState($state); return false; } $prepend = $tip instanceof Document || !$tip->getParent() instanceof Document && $context->getBlockCloser()->areAllClosed(); $context->addBlock(new Attributes($attributes, $prepend ? Attributes::PREPEND : Attributes::APPEND)); $context->setBlocksParsed(true); return true; }
/** * @param ContextInterface $context * @param Cursor $cursor * * @return bool */ public function parse(ContextInterface $context, Cursor $cursor) { $previousState = $cursor->saveState(); $indent = $cursor->advanceToFirstNonSpace(); $fence = $cursor->match('/^`{3,}(?!.*`)|^~{3,}(?!.*~)/'); if (!$fence) { $cursor->restoreState($previousState); return false; } // fenced code block $fenceLength = strlen($fence); $context->addBlock(new FencedCode($fenceLength, $fence[0], $indent)); return true; }
public static function parse(Cursor $cursor) { if (null === self::$regexp) { $regex = RegexHelper::getInstance(); self::$regexp = sprintf('/^\\s*([.#][_a-z0-9-]+|%s%s)(?<!})\\s*/i', $regex->getPartialRegex(RegexHelper::ATTRIBUTENAME), $regex->getPartialRegex(RegexHelper::ATTRIBUTEVALUESPEC)); } $state = $cursor->saveState(); $cursor->advanceToFirstNonSpace(); if ('{' !== $cursor->getCharacter()) { $cursor->restoreState($state); return []; } $cursor->advanceBy(1); if (':' === $cursor->getCharacter()) { $cursor->advanceBy(1); } $attributes = []; while ($attribute = trim($cursor->match(self::$regexp))) { if ('#' === $attribute[0]) { $attributes['id'] = substr($attribute, 1); continue; } if ('.' === $attribute[0]) { $attributes['class'][] = substr($attribute, 1); continue; } list($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 ('class' === strtolower(trim($name))) { foreach (array_filter(explode(' ', trim($value))) as $class) { $attributes['class'][] = $class; } } else { $attributes[trim($name)] = trim($value); } } if (0 === $cursor->advanceWhileMatches('}')) { $cursor->restoreState($state); return []; } if (isset($attributes['class'])) { $attributes['class'] = implode(' ', $attributes['class']); } return $attributes; }
public function parse(ContextInterface $context, Cursor $cursor) { $state = $cursor->saveState(); $attributes = AttributesUtils::parse($cursor); if (empty($attributes)) { return false; } if (null !== $cursor->getFirstNonSpaceCharacter()) { $cursor->restoreState($state); return false; } $context->addBlock(new Attributes($attributes)); $context->setBlocksParsed(true); return true; }
/** * @param ContextInterface $context * @param Cursor $cursor * * @return bool */ public function parse(ContextInterface $context, Cursor $cursor) { if ($cursor->isIndented()) { return false; } $previousState = $cursor->saveState(); $cursor->advanceToFirstNonSpace(); $fence = $cursor->match('/^\\[TOC\\]/'); if (is_null($fence)) { $cursor->restoreState($previousState); return false; } $context->addBlock(new TableOfContents()); return true; }
/** * Attempt to parse a link reference, modifying the refmap. * * @param Cursor $cursor * * @return bool */ public function parse(Cursor $cursor) { if ($cursor->isAtEnd()) { return false; } $initialState = $cursor->saveState(); $matchChars = LinkParserHelper::parseLinkLabel($cursor); if ($matchChars === 0) { $cursor->restoreState($initialState); return false; } // We need to trim the opening and closing brackets from the previously-matched text $label = substr($cursor->getPreviousText(), 1, -1); if (preg_match('/[^\\s]/', $label) === 0) { $cursor->restoreState($initialState); return false; } if ($cursor->getCharacter() !== ':') { $cursor->restoreState($initialState); return false; } // Advance past the colon $cursor->advance(); // Link URL $cursor->advanceToFirstNonSpace(); $destination = LinkParserHelper::parseLinkDestination($cursor); if (empty($destination)) { $cursor->restoreState($initialState); return false; } $previousState = $cursor->saveState(); $cursor->advanceToFirstNonSpace(); $title = LinkParserHelper::parseLinkTitle($cursor); if ($title === null) { $title = ''; $cursor->restoreState($previousState); } // Make sure we're at line end: if ($cursor->match('/^ *(?:\\n|$)/') === null) { $cursor->restoreState($initialState); return false; } if (!$this->referenceMap->contains($label)) { $reference = new Reference($label, $destination, $title); $this->referenceMap->addReference($reference); } return true; }
/** * @param Cursor $cursor * @param int $markerLength * * @return int */ private function calculateListMarkerPadding(Cursor $cursor, $markerLength) { $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; }
/** * @param Cursor $cursor * @param int $markerLength * * @return int */ private function calculateListMarkerPadding(Cursor $cursor, $markerLength) { $start = $cursor->saveState(); $spacesStartCol = $cursor->getColumn(); do { $cursor->advanceBy(1, true); $nextChar = $cursor->getCharacter(); } while ($cursor->getColumn() - $spacesStartCol < 5 && ($nextChar === ' ' || $nextChar === "\t")); $blankItem = $cursor->peek() === null; $spacesAfterMarker = $cursor->getColumn() - $spacesStartCol; if ($spacesAfterMarker >= 5 || $spacesAfterMarker < 1 || $blankItem) { $cursor->restoreState($start); if ($cursor->peek() === ' ') { $cursor->advanceBy(1, true); } return $markerLength + 1; } return $markerLength + $spacesAfterMarker; }
/** * @param ContextInterface $context * @param Cursor $cursor * * @return bool */ public function parse(ContextInterface $context, Cursor $cursor) { if ($cursor->isIndented()) { return false; } if ($cursor->getFirstNonSpaceCharacter() !== '<') { return false; } $savedState = $cursor->saveState(); $cursor->advanceToFirstNonSpace(); $line = $cursor->getRemainder(); for ($blockType = 1; $blockType <= 7; $blockType++) { $match = RegexHelper::matchAt(RegexHelper::getHtmlBlockOpenRegex($blockType), $line); if ($match !== null && ($blockType < 7 || !$context->getContainer() instanceof Paragraph)) { $cursor->restoreState($savedState); $context->addBlock(new HtmlBlock($blockType)); $context->setBlocksParsed(true); return true; } } $cursor->restoreState($savedState); return false; }
/** * @param Cursor $cursor * @param ReferenceMap $referenceMap * @param Delimiter $opener * @param int $startPos * * @return Reference|null */ protected function tryParseReference(Cursor $cursor, ReferenceMap $referenceMap, Delimiter $opener, $startPos) { $savePos = $cursor->saveState(); $cursor->advanceToFirstNonSpace(); $beforeLabel = $cursor->getPosition(); $n = LinkParserHelper::parseLinkLabel($cursor); if ($n === 0 || $n === 2) { // Empty or missing second label $reflabel = mb_substr($cursor->getLine(), $opener->getIndex(), $startPos - $opener->getIndex(), 'utf-8'); } else { $reflabel = mb_substr($cursor->getLine(), $beforeLabel + 1, $n - 2, 'utf-8'); } if ($n === 0) { // If shortcut reference link, rewind before spaces we skipped $cursor->restoreState($savePos); } return $referenceMap->getReference($reflabel); }
/** * Attempt to parse a link reference, modifying the refmap. * * @param Cursor $cursor * * @return bool */ public function parse(Cursor $cursor) { if ($cursor->isAtEnd()) { return false; } $initialState = $cursor->saveState(); $matchChars = LinkParserHelper::parseLinkLabel($cursor); if ($matchChars === 0) { $cursor->restoreState($initialState); return false; } // We need to trim the opening and closing brackets from the previously-matched text $label = substr($cursor->getPreviousText(), 1, -1); if (preg_match('/[^\\s]/', $label) === 0) { $cursor->restoreState($initialState); return false; } if ($cursor->getCharacter() !== ':') { $cursor->restoreState($initialState); return false; } // Advance past the colon $cursor->advance(); // Link URL $cursor->advanceToFirstNonSpace(); $destination = LinkParserHelper::parseLinkDestination($cursor); if (empty($destination)) { $cursor->restoreState($initialState); return false; } $previousState = $cursor->saveState(); $cursor->advanceToFirstNonSpace(); $title = LinkParserHelper::parseLinkTitle($cursor); if ($title === null) { $title = ''; $cursor->restoreState($previousState); } // Make sure we're at line end: $atLineEnd = true; if ($cursor->match('/^ *(?:\\n|$)/') === null) { if ($title === '') { $atLineEnd = false; } else { // The potential title we found is not at the line end, // but it could still be a legal link reference if we // discard the title $title = ''; // rewind before spaces $cursor->restoreState($previousState); // and instead check if the link URL is at the line end $atLineEnd = $cursor->match('/^ *(?:\\n|$)/') !== null; } } if (!$atLineEnd) { $cursor->restoreState($initialState); return false; } if (!$this->referenceMap->contains($label)) { $reference = new Reference($label, $destination, $title); $this->referenceMap->addReference($reference); } return true; }