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; }
/** * @param ContextInterface $context * @param Cursor $cursor * * @return bool */ public function parse(ContextInterface $context, Cursor $cursor) { if ($cursor->getFirstNonSpaceCharacter() !== 'A' || $cursor->getCharacter($cursor->getFirstNonSpacePosition() + 1) !== '>') { return false; } $cursor->advanceToFirstNonSpace(); if ($cursor->peek() === '>') { $cursor->advanceBy(2); if ($cursor->getCharacter() === ' ') { $cursor->advance(); } } $context->addBlock(new Aside()); return true; }
public function parse(ContextInterface $context, Cursor $cursor) { $inlineParserContext = new InlineParserContext($cursor); while (($character = $cursor->getCharacter()) !== null) { if ($matchingParsers = $this->environment->getInlineParsersForCharacter($character)) { foreach ($matchingParsers as $parser) { if ($parser->parse($context, $inlineParserContext)) { continue 2; } } } // We reach here if none of the parsers can handle the input // Attempt to match multiple non-special characters at once $text = $cursor->match($this->environment->getInlineParserCharacterRegex()); // This might fail if we're currently at a special character which wasn't parsed; if so, just add that character if ($text === null) { $cursor->advance(); $text = $character; } $lastInline = $inlineParserContext->getInlines()->last(); if ($lastInline instanceof Text && !isset($lastInline->data['delim'])) { $lastInline->append($text); } else { $inlineParserContext->getInlines()->add(new Text($text)); } } foreach ($this->environment->getInlineProcessors() as $inlineProcessor) { $inlineProcessor->processInlines($inlineParserContext->getInlines(), $inlineParserContext->getDelimiterStack()); } return $inlineParserContext->getInlines(); }
/** * @param ContextInterface $context * @param Cursor $cursor * * @return bool */ public function parse(ContextInterface $context, Cursor $cursor) { if (!in_array($cursor->getFirstNonSpaceCharacter(), IconBlock::getIconBlockTypes()) || $cursor->getCharacter($cursor->getFirstNonSpacePosition() + 1) !== '>') { return false; } $type = $cursor->getFirstNonSpaceCharacter(); $cursor->advanceToFirstNonSpace(); if ($cursor->peek() === '>') { $cursor->advanceBy(2); if ($cursor->getCharacter() === ' ') { $cursor->advance(); } } $context->addBlock(new IconBlock($type)); return true; }
/** * @param ContextInterface $context * @param Cursor $cursor * * @return bool */ protected function parseReferences(ContextInterface $context, Cursor $cursor) { $referenceFound = false; while ($cursor->getCharacter() === '[' && $context->getReferenceParser()->parse($cursor)) { $this->finalStringContents = $cursor->getRemainder(); $referenceFound = true; } return $referenceFound; }
/** * @param ContextInterface $context * @param Cursor $cursor * * @return ArrayCollection */ public function parse(ContextInterface $context, Cursor $cursor) { $inlineParserContext = new InlineParserContext($cursor); while (($character = $cursor->getCharacter()) !== null) { if (!$this->parseCharacter($character, $context, $inlineParserContext)) { $this->addPlainText($character, $inlineParserContext); } } $this->processInlines($inlineParserContext); return $inlineParserContext->getInlines(); }
public function matchesNextLine(Cursor $cursor) { if ($cursor->getIndent() <= 3 && $cursor->getFirstNonSpaceCharacter() === '>') { $cursor->advanceToFirstNonSpace(); $cursor->advance(); if ($cursor->getCharacter() === ' ') { $cursor->advance(); } return true; } return false; }
/** * @param ContextInterface $context * @param Cursor $cursor * * @return bool */ public function parse(ContextInterface $context, Cursor $cursor) { if ($cursor->getFirstNonSpaceCharacter() !== '>') { return false; } $cursor->advanceToFirstNonSpace(); $cursor->advance(); if ($cursor->getCharacter() === ' ') { $cursor->advance(); } $context->addBlock(new BlockQuote()); return true; }
public function matchesNextLine(Cursor $cursor) { if ($cursor->getIndent() <= 3 && in_array($cursor->getFirstNonSpaceCharacter(), static::getIconBlockTypes())) { $cursor->advanceToFirstNonSpace(); if ($cursor->peek() === '>') { $cursor->advanceBy(2); if ($cursor->getCharacter() === ' ') { $cursor->advance(); } return true; } } return false; }
/** * @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 Cursor $cursor * @param ReferenceMap $referenceMap * @param Delimiter $opener * @param int $startPos * * @return array|bool */ protected function tryParseLink(Cursor $cursor, ReferenceMap $referenceMap, Delimiter $opener, $startPos) { // Check to see if we have a link/image // Inline link? if ($cursor->getCharacter() == '(') { if ($result = $this->tryParseInlineLinkAndTitle($cursor)) { return $result; } } elseif ($link = $this->tryParseReference($cursor, $referenceMap, $opener, $startPos)) { return ['url' => $link->getDestination(), 'title' => $link->getTitle()]; } return false; }
/** * @param Cursor $cursor * * @return array|bool */ protected function tryParseInlineLinkAndTitle(Cursor $cursor) { if ($cursor->getCharacter() !== '(') { return false; } $previousState = $cursor->saveState(); $cursor->advance(); $cursor->advanceToFirstNonSpace(); if (($dest = LinkParserHelper::parseLinkDestination($cursor)) === null) { $cursor->restoreState($previousState); return false; } $cursor->advanceToFirstNonSpace(); $title = null; // make sure there's a space before the title: if (preg_match(RegexHelper::REGEX_WHITESPACE_CHAR, $cursor->peek(-1))) { $title = LinkParserHelper::parseLinkTitle($cursor) ?: ''; } $cursor->advanceToFirstNonSpace(); if ($cursor->match('/^\\)/') === null) { $cursor->restoreState($previousState); return false; } return ['url' => $dest, 'title' => $title]; }