/**
  * @param ContextInterface $context
  * @param InlineParserContext $inline_context
  *
  * @return bool
  */
 public function parse(ContextInterface $context, InlineParserContext $inline_context)
 {
     $cursor = $inline_context->getCursor();
     $character = $cursor->getCharacter();
     if ($cursor->peek(1) !== $character) {
         return false;
     }
     $tildes = $cursor->match('/^~~+/');
     if ($tildes === '') {
         return false;
     }
     $previous_state = $cursor->saveState();
     while ($matching_tildes = $cursor->match('/~~+/m')) {
         if ($matching_tildes === $tildes) {
             $text = mb_substr($cursor->getLine(), $previous_state->getCurrentPosition(), $cursor->getPosition() - $previous_state->getCurrentPosition() - strlen($tildes), 'utf-8');
             $text = preg_replace('/[ \\n]+/', ' ', $text);
             $inline_context->getInlines()->add(new Strikethrough(trim($text)));
             return true;
         }
     }
     // If we got here, we didn't match a closing tilde pair sequence
     $cursor->restoreState($previous_state);
     $inline_context->getInlines()->add(new Text($tildes));
     return true;
 }
Esempio n. 2
0
 /**
  * Parse @mentions from a string of text
  * https://github.com/thephpleague/commonmark/blob/gh-pages/customization/inline-parsing.md#example
  *
  * @param ContextInterface $context
  * @param InlineParserContext $inlineContext
  * @return bool
  */
 public function parse(ContextInterface $context, InlineParserContext $inlineContext)
 {
     $cursor = $inlineContext->getCursor();
     $previousChar = $cursor->peek(-1);
     if ($previousChar !== null && $previousChar !== ' ') {
         return false;
     }
     $previousState = $cursor->saveState();
     $cursor->advance();
     $handle = $cursor->match('/^\\w+/');
     if (empty($handle)) {
         $cursor->restoreState($previousState);
         return false;
     }
     $userCache = new UserCache();
     $usernames = $userCache->usernames();
     $found = in_array($handle, $usernames, true);
     if (!$found) {
         $cursor->restoreState($previousState);
         return false;
     }
     $users = $userCache->users();
     $userKey = $this->searchArray($users, $handle);
     $user = $users[$userKey];
     $url = $user['url'];
     $inlineContext->getInlines()->add(new Link($url, '@' . $handle));
     return true;
 }
Esempio n. 3
0
 public function parse(InlineParserContext $inlineContext)
 {
     $cursor = $inlineContext->getCursor();
     // The 'g/' prefix must not have any other characters immediately prior
     $previousChar = $cursor->peek(-1);
     $nextChar = $cursor->peek(1);
     if ($previousChar !== null && $previousChar !== ' ') {
         // peek() doesn't modify the cursor, so no need to restore state first
         return false;
     }
     if ($nextChar !== '/') {
         return false;
     }
     // Save the cursor state in case we need to rewind and bail
     $previousState = $cursor->saveState();
     // Advance past the 'g/' prefix to keep parsing simpler
     $cursor->advanceBy(2);
     // Parse the handle
     $handle = $cursor->match('/^[A-Za-z0-9_]{1,32}(?!\\w)/');
     if (empty($handle)) {
         // Regex failed to match; this isn't a valid username
         $cursor->restoreState($previousState);
         return false;
     }
     $group = Group::name($handle)->first();
     if (!$group) {
         $cursor->restoreState($previousState);
         return false;
     }
     $groupUrl = route('group_contents', $group, false);
     $inlineContext->getContainer()->appendChild(new Link($groupUrl, 'g/' . $handle));
     return true;
 }
Esempio n. 4
0
 /**
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(InlineParserContext $inlineContext)
 {
     $character = $inlineContext->getCursor()->getCharacter();
     if (in_array($character, $this->double)) {
         $character = '“';
     } elseif (in_array($character, $this->single)) {
         $character = '’';
     } else {
         return false;
     }
     $cursor = $inlineContext->getCursor();
     $charBefore = $cursor->peek(-1);
     if ($charBefore === null) {
         $charBefore = "\n";
     }
     $cursor->advance();
     $charAfter = $cursor->getCharacter();
     if ($charAfter === null) {
         $charAfter = "\n";
     }
     $afterIsWhitespace = preg_match('/\\pZ|\\s/u', $charAfter);
     $afterIsPunctuation = preg_match(RegexHelper::REGEX_PUNCTUATION, $charAfter);
     $beforeIsWhitespace = preg_match('/\\pZ|\\s/u', $charBefore);
     $beforeIsPunctuation = preg_match(RegexHelper::REGEX_PUNCTUATION, $charBefore);
     $leftFlanking = !$afterIsWhitespace && !($afterIsPunctuation && !$beforeIsWhitespace && !$beforeIsPunctuation);
     $rightFlanking = !$beforeIsWhitespace && !($beforeIsPunctuation && !$afterIsWhitespace && !$afterIsPunctuation);
     $canOpen = $leftFlanking && !$rightFlanking;
     $canClose = $rightFlanking;
     $node = new Text($character, ['delim' => true]);
     $inlineContext->getContainer()->appendChild($node);
     // Add entry to stack to this opener
     $inlineContext->getDelimiterStack()->push(new Delimiter($character, 1, $node, $canOpen, $canClose));
     return true;
 }
Esempio n. 5
0
 /**
  * Parse a line and determine if it contains an emoji.
  *
  * If it does, then we do the necessary.
  *
  * @return bool
  */
 public function parse(ContextInterface $context, InlineParserContext $inlineContext)
 {
     $cursor = $inlineContext->getCursor();
     $previous = $cursor->peek(-1);
     if ($previous !== null && $previous !== ' ') {
         return false;
     }
     $saved = $cursor->saveState();
     $cursor->advance();
     $handle = $cursor->match('/^[a-z0-9\\+\\-_]+:/');
     if (!$handle) {
         $cursor->restoreState($saved);
         return false;
     }
     $next = $cursor->peek(0);
     if ($next !== null && $next !== ' ') {
         $cursor->restoreState($saved);
         return false;
     }
     $key = substr($handle, 0, -1);
     if (!array_key_exists($key, $this->map)) {
         $cursor->restoreState($saved);
         return false;
     }
     $inline = new Image($this->map[$key], $key);
     $inline->data['attributes'] = ['class' => 'emoji', 'data-emoji' => $key];
     $inlineContext->getInlines()->add($inline);
     return true;
 }
 /**
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(InlineParserContext $inlineContext)
 {
     $cursor = $inlineContext->getCursor();
     $ch = $cursor->getCharacter();
     // Ellipses
     if ($ch === '.' && ($matched = $cursor->match('/^\\.( ?\\.)\\1/'))) {
         $inlineContext->getContainer()->appendChild(new Text('…'));
         return true;
     } elseif ($ch === '-' && ($matched = $cursor->match('/^(?<!-)(-{2,})/'))) {
         $count = strlen($matched);
         $en_dash = '–';
         $en_count = 0;
         $em_dash = '—';
         $em_count = 0;
         if ($count % 3 === 0) {
             // If divisible by 3, use all em dashes
             $em_count = $count / 3;
         } elseif ($count % 2 === 0) {
             // If divisible by 2, use all en dashes
             $en_count = $count / 2;
         } elseif ($count % 3 === 2) {
             // If 2 extra dashes, use en dash for last 2; em dashes for rest
             $em_count = ($count - 2) / 3;
             $en_count = 1;
         } else {
             // Use en dashes for last 4 hyphens; em dashes for rest
             $em_count = ($count - 4) / 3;
             $en_count = 2;
         }
         $inlineContext->getContainer()->appendChild(new Text(str_repeat($em_dash, $em_count) . str_repeat($en_dash, $en_count)));
         return true;
     }
     return false;
 }
Esempio n. 7
0
 /**
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(InlineParserContext $inlineContext)
 {
     $character = $inlineContext->getCursor()->getCharacter();
     if (!in_array($character, $this->getCharacters())) {
         return false;
     }
     $numDelims = 0;
     $cursor = $inlineContext->getCursor();
     $charBefore = $cursor->peek(-1);
     if ($charBefore === null) {
         $charBefore = "\n";
     }
     while ($cursor->peek($numDelims) === $character) {
         ++$numDelims;
     }
     if ($numDelims === 0) {
         return false;
     }
     // Skip single delims if emphasis is disabled
     if ($numDelims === 1 && !$this->config->getConfig('enable_em')) {
         return false;
     }
     $cursor->advanceBy($numDelims);
     $charAfter = $cursor->getCharacter();
     if ($charAfter === null) {
         $charAfter = "\n";
     }
     list($canOpen, $canClose) = $this->determineCanOpenOrClose($charBefore, $charAfter, $character);
     $node = new Text($cursor->getPreviousText(), ['delim' => true, 'emphasis_config' => $this->config]);
     $inlineContext->getContainer()->appendChild($node);
     // Add entry to stack to this opener
     $delimiter = new Delimiter($character, $numDelims, $node, $canOpen, $canClose);
     $inlineContext->getDelimiterStack()->push($delimiter);
     return true;
 }
Esempio n. 8
0
 /**
  * @param ContextInterface $context
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(ContextInterface $context, InlineParserContext $inlineContext)
 {
     if ($m = $inlineContext->getCursor()->match(RegexHelper::REGEX_ENTITY)) {
         $inlineContext->getInlines()->add(new Text(Html5Entities::decodeEntity($m)));
         return true;
     }
     return false;
 }
Esempio n. 9
0
 /**
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(InlineParserContext $inlineContext)
 {
     if ($m = $inlineContext->getCursor()->match('/^' . RegexHelper::REGEX_ENTITY . '/i')) {
         $inlineContext->getContainer()->appendChild(new Text(Html5Entities::decodeEntity($m)));
         return true;
     }
     return false;
 }
Esempio n. 10
0
 /**
  * @param ContextInterface $context
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(ContextInterface $context, InlineParserContext $inlineContext)
 {
     $cursor = $inlineContext->getCursor();
     if ($m = $cursor->match(RegexHelper::getInstance()->getHtmlTagRegex())) {
         $inlineContext->getInlines()->add(new Html($m));
         return true;
     }
     return false;
 }
 /**
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(InlineParserContext $inlineContext)
 {
     $cursor = $inlineContext->getCursor();
     if ($m = $cursor->match(RegexHelper::getInstance()->getHtmlTagRegex())) {
         $inlineContext->getContainer()->appendChild(new HtmlInline($m));
         return true;
     }
     return false;
 }
Esempio n. 12
0
 /**
  * @param ContextInterface $context
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(ContextInterface $context, InlineParserContext $inlineContext)
 {
     $cursor = $inlineContext->getCursor();
     if ($cursor->peek() === '[') {
         $cursor->advanceBy(2);
         $inlineContext->getInlines()->add(new Text('![', array('delim' => true)));
         // Add entry to stack for this opener
         $delimiter = new Delimiter('!', 1, $inlineContext->getInlines()->count() - 1, true, false, $cursor->getPosition());
         $inlineContext->getDelimiterStack()->push($delimiter);
         return true;
     }
     return false;
 }
 /**
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(InlineParserContext $inlineContext)
 {
     $cursor = $inlineContext->getCursor();
     if ($cursor->peek() === '[') {
         $cursor->advanceBy(2);
         $node = new Text('![', ['delim' => true]);
         $inlineContext->getContainer()->appendChild($node);
         // Add entry to stack for this opener
         $delimiter = new Delimiter('!', 1, $node, true, false, $cursor->getPosition());
         $inlineContext->getDelimiterStack()->push($delimiter);
         return true;
     }
     return false;
 }
Esempio n. 14
0
 /**
  * @param ContextInterface $context
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(ContextInterface $context, InlineParserContext $inlineContext)
 {
     $cursor = $inlineContext->getCursor();
     if ($m = $cursor->match(self::EMAIL_REGEX)) {
         $email = substr($m, 1, -1);
         $inlineContext->getInlines()->add(new Link('mailto:' . UrlEncoder::unescapeAndEncode($email), $email));
         return true;
     } elseif ($m = $cursor->match(self::OTHER_LINK_REGEX)) {
         $dest = substr($m, 1, -1);
         $inlineContext->getInlines()->add(new Link(UrlEncoder::unescapeAndEncode($dest), $dest));
         return true;
     }
     return false;
 }
 public function parse(ContextInterface $context, InlineParserContext $inlineContext)
 {
     $cursor = $inlineContext->getCursor();
     if ($cursor->getFirstNonSpaceCharacter() !== '{') {
         return false;
     }
     $char = $cursor->getCharacter();
     if ('{' === $char) {
         $char = (string) $cursor->getCharacter($cursor->getPosition() - 1);
     }
     $attributes = AttributesUtils::parse($cursor);
     if (empty($attributes)) {
         return false;
     }
     $inlineContext->getInlines()->add(new InlineAttributes($attributes, ' ' === $char || '' === $char));
     return true;
 }
Esempio n. 16
0
 /**
  * @param string              $character
  * @param InlineParserContext $inlineParserContext
  */
 private function addPlainText($character, InlineParserContext $inlineParserContext)
 {
     // We reach here if none of the parsers can handle the input
     // Attempt to match multiple non-special characters at once
     $text = $inlineParserContext->getCursor()->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) {
         $inlineParserContext->getCursor()->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));
     }
 }
 /**
  * {@inheritdoc}
  */
 public function parse(ContextInterface $context, InlineParserContext $inline_context)
 {
     $cursor = $inline_context->getCursor();
     // The @ symbol must not have any other characters immediately prior.
     $previous_char = $cursor->peek(-1);
     if ($previous_char !== NULL && $previous_char !== ' ') {
         // peek() doesn't modify the cursor, so no need to restore state first.
         return FALSE;
     }
     // Save the cursor state in case we need to rewind and bail.
     $previous_state = $cursor->saveState();
     // Advance past the @ symbol to keep parsing simpler.
     $cursor->advance();
     // Parse the handle.
     $text = $cursor->match('/^[^\\s]+/');
     $url = '';
     $title = '';
     $type = $this->getSetting('type');
     if ($type === 'user') {
         $user = user_load_by_name($text);
         if ((!$user || !$user->uid) && is_numeric($text)) {
             $user = user_load((int) $text);
         }
         if ($user && $user->uid) {
             $url = url("user/{$user->uid}", ['absolute' => TRUE]);
             $title = t('View user profile.');
             if ($this->getSetting('format_username')) {
                 $text = format_username($user);
             }
         } else {
             $text = FALSE;
         }
     } elseif ($type === 'url' && ($url = $this->getSetting('url')) && strpos($url, '[text]') !== FALSE) {
         $url = str_replace('[text]', $text, $url);
     } else {
         $text = FALSE;
     }
     // Regex failed to match; this isn't a valid @ handle.
     if (empty($text) || empty($url)) {
         $cursor->restoreState($previous_state);
         return FALSE;
     }
     $inline_context->getInlines()->add(new Link($url, '@' . $text, $title));
     return TRUE;
 }
Esempio n. 18
0
 /**
  * Parse @mentions from a string of text
  * https://github.com/thephpleague/commonmark/blob/gh-pages/customization/inline-parsing.md#example
  *
  * @param ContextInterface $context
  * @param InlineParserContext $inlineContext
  * @return bool
  */
 public function parse(ContextInterface $context, InlineParserContext $inlineContext)
 {
     $cursor = $inlineContext->getCursor();
     $previousChar = $cursor->peek(-1);
     if ($previousChar !== null && $previousChar !== ' ') {
         return false;
     }
     $previousState = $cursor->saveState();
     $cursor->advance();
     $handle = $cursor->match('/^\\w+/');
     if (empty($handle)) {
         $cursor->restoreState($previousState);
         return false;
     }
     $profileUrl = 'https://cribbb.com/' . $handle;
     $inlineContext->getInlines()->add(new Link($profileUrl, '@' . $handle));
     return true;
 }
 /**
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(InlineParserContext $inlineContext)
 {
     $character = $inlineContext->getCursor()->getCharacter();
     if (!in_array($character, $this->getCharacters())) {
         return false;
     }
     $numDelims = 0;
     $cursor = $inlineContext->getCursor();
     $charBefore = $cursor->peek(-1);
     if ($charBefore === null) {
         $charBefore = "\n";
     }
     while ($cursor->peek($numDelims) === $character) {
         ++$numDelims;
     }
     // Skip single delims if emphasis is disabled
     if ($numDelims === 1 && !$this->config->getConfig('enable_em')) {
         return false;
     }
     $cursor->advanceBy($numDelims);
     $charAfter = $cursor->getCharacter();
     if ($charAfter === null) {
         $charAfter = "\n";
     }
     $afterIsWhitespace = preg_match('/\\pZ|\\s/u', $charAfter);
     $afterIsPunctuation = preg_match(RegexHelper::REGEX_PUNCTUATION, $charAfter);
     $beforeIsWhitespace = preg_match('/\\pZ|\\s/u', $charBefore);
     $beforeIsPunctuation = preg_match(RegexHelper::REGEX_PUNCTUATION, $charBefore);
     $leftFlanking = $numDelims > 0 && !$afterIsWhitespace && !($afterIsPunctuation && !$beforeIsWhitespace && !$beforeIsPunctuation);
     $rightFlanking = $numDelims > 0 && !$beforeIsWhitespace && !($beforeIsPunctuation && !$afterIsWhitespace && !$afterIsPunctuation);
     if ($character === '_') {
         $canOpen = $leftFlanking && (!$rightFlanking || $beforeIsPunctuation);
         $canClose = $rightFlanking && (!$leftFlanking || $afterIsPunctuation);
     } else {
         $canOpen = $leftFlanking;
         $canClose = $rightFlanking;
     }
     $node = new Text($cursor->getPreviousText(), ['delim' => true, 'emphasis_config' => $this->config]);
     $inlineContext->getContainer()->appendChild($node);
     // Add entry to stack to this opener
     $delimiter = new Delimiter($character, $numDelims, $node, $canOpen, $canClose);
     $inlineContext->getDelimiterStack()->push($delimiter);
     return true;
 }
 /**
  * {@inheritdoc}
  */
 public function parse(ContextInterface $context, InlineParserContext $inline_context)
 {
     $cursor = $inline_context->getCursor();
     // The # symbol must not have any other characters immediately prior.
     $previous_char = $cursor->peek(-1);
     if ($previous_char !== NULL && $previous_char !== ' ' && $previous_char !== '[') {
         // peek() doesn't modify the cursor, so no need to restore state first.
         return FALSE;
     }
     // Save the cursor state in case we need to rewind and bail.
     $previous_state = $cursor->saveState();
     // Advance past the # symbol to keep parsing simpler.
     $cursor->advance();
     // Parse the handle.
     $text = $cursor->match('/^[^\\s\\]]+/');
     $url = FALSE;
     $title = FALSE;
     $type = $this->getSetting('type');
     if ($type === 'node' && is_numeric($text) && ($node = node_load($text))) {
         $url = url("node/{$node->nid}", ['absolute' => TRUE]);
         if ($this->getSetting('node_title') && !empty($node->title)) {
             $text = $node->title;
         } else {
             $text = "#{$text}";
         }
     } elseif ($type === 'url' && ($url = $this->getSetting('url')) && strpos($url, '[text]') !== FALSE) {
         $url = str_replace('[text]', $text, $url);
         if ($this->getSetting('url_title') && ($title = $this->getUrlTitle($url))) {
             $text = $title;
             $title = FALSE;
         }
     } else {
         $text = FALSE;
     }
     // Regex failed to match; this isn't a valid @ handle.
     if (empty($text) || empty($url)) {
         $cursor->restoreState($previous_state);
         return FALSE;
     }
     $inline_context->getInlines()->add(new Link($url, $text, $title));
     return TRUE;
 }
 /**
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(InlineParserContext $inlineContext)
 {
     $cursor = $inlineContext->getCursor();
     if ($cursor->getCharacter() !== '\\') {
         return false;
     }
     $nextChar = $cursor->peek();
     if ($nextChar === "\n") {
         $cursor->advanceBy(2);
         $inlineContext->getContainer()->appendChild(new Newline(Newline::HARDBREAK));
         return true;
     } elseif ($nextChar !== null && preg_match('/' . RegexHelper::REGEX_ESCAPABLE . '/', $nextChar)) {
         $cursor->advanceBy(2);
         $inlineContext->getContainer()->appendChild(new Text($nextChar));
         return true;
     }
     $cursor->advance();
     $inlineContext->getContainer()->appendChild(new Text('\\'));
     return true;
 }
 /**
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(InlineParserContext $inlineContext)
 {
     $cursor = $inlineContext->getCursor();
     $delimiterStack = $inlineContext->getDelimiterStack();
     if ($cursor->peek(-1) !== '[') {
         return false;
     }
     if ($cursor->peek(-2) == '!' || $cursor->peek(-1) !== '[' || $cursor->peek(1) !== ']' || $cursor->peek(2) !== ' ') {
         return false;
     }
     $status = $cursor->peek(0) == 'x';
     $cursor->advanceBy(2);
     // Add entry to stack for this opener
     $delimiter = new Delimiter('[', 1, $inlineContext->getContainer()->firstChild(), true, false, 0);
     $delimiterStack->push($delimiter);
     $opener = $delimiterStack->searchByCharacter(['[']);
     $opener->getInlineNode()->replaceWith(new TaskListsCheckbox($status));
     $delimiterStack->removeDelimiter($opener);
     return true;
 }
Esempio n. 23
0
 /**
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(InlineParserContext $inlineContext)
 {
     $inlineContext->getCursor()->advance();
     // Check previous inline for trailing spaces
     $spaces = 0;
     $lastInline = $inlineContext->getContainer()->lastChild();
     if ($lastInline && $lastInline instanceof Text) {
         $trimmed = rtrim($lastInline->getContent(), ' ');
         $spaces = strlen($lastInline->getContent()) - strlen($trimmed);
         if ($spaces) {
             $lastInline->setContent($trimmed);
         }
     }
     if ($spaces >= 2) {
         $inlineContext->getContainer()->appendChild(new Newline(Newline::HARDBREAK));
     } else {
         $inlineContext->getContainer()->appendChild(new Newline(Newline::SOFTBREAK));
     }
     return true;
 }
Esempio n. 24
0
 /**
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(InlineParserContext $inlineContext)
 {
     $cursor = $inlineContext->getCursor();
     $ticks = $cursor->match('/^`+/');
     if ($ticks === '') {
         return false;
     }
     $previousState = $cursor->saveState();
     while ($matchingTicks = $cursor->match('/`+/m')) {
         if ($matchingTicks === $ticks) {
             $code = mb_substr($cursor->getLine(), $previousState->getCurrentPosition(), $cursor->getPosition() - $previousState->getCurrentPosition() - strlen($ticks), 'utf-8');
             $c = preg_replace(RegexHelper::REGEX_WHITESPACE, ' ', $code);
             $inlineContext->getContainer()->appendChild(new Code(trim($c)));
             return true;
         }
     }
     // If we got here, we didn't match a closing backtick sequence
     $cursor->restoreState($previousState);
     $inlineContext->getContainer()->appendChild(new Text($ticks));
     return true;
 }
Esempio n. 25
0
 /**
  * @param ContextInterface $context
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(ContextInterface $context, InlineParserContext $inlineContext)
 {
     $cursor = $inlineContext->getCursor();
     $ticks = $cursor->match('/^`+/');
     if ($ticks === '') {
         return false;
     }
     $previousState = $cursor->saveState();
     while ($matchingTicks = $cursor->match('/`+/m')) {
         if ($matchingTicks === $ticks) {
             $code = substr($cursor->getLine(), $previousState->getCurrentPosition(), $cursor->getPosition() - $previousState->getCurrentPosition() - strlen($ticks));
             $c = preg_replace('/[ \\n]+/', ' ', $code);
             $inlineContext->getInlines()->add(new Code(trim($c)));
             return true;
         }
     }
     // If we got here, we didn't match a closing backtick sequence
     $cursor->restoreState($previousState);
     $inlineContext->getInlines()->add(new Text($ticks));
     return true;
 }
Esempio n. 26
0
 /**
  * @param ContextInterface $context
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(ContextInterface $context, InlineParserContext $inlineContext)
 {
     $character = $inlineContext->getCursor()->getCharacter();
     if (!in_array($character, $this->getCharacters())) {
         return false;
     }
     $numDelims = 0;
     $cursor = $inlineContext->getCursor();
     $charBefore = $cursor->peek(-1);
     if ($charBefore === null) {
         $charBefore = "\n";
     }
     while ($cursor->peek($numDelims) === $character) {
         ++$numDelims;
     }
     $cursor->advanceBy($numDelims);
     $charAfter = $cursor->getCharacter();
     if ($charAfter === null) {
         $charAfter = "\n";
     }
     $leftFlanking = $numDelims > 0 && !preg_match('/\\pZ|\\s/u', $charAfter) && !(preg_match(RegexHelper::REGEX_PUNCTUATION, $charAfter) && !preg_match('/\\pZ|\\s/u', $charBefore) && !preg_match(RegexHelper::REGEX_PUNCTUATION, $charBefore));
     $rightFlanking = $numDelims > 0 && !preg_match('/\\pZ|\\s/u', $charBefore) && !(preg_match(RegexHelper::REGEX_PUNCTUATION, $charBefore) && !preg_match('/\\pZ|\\s/u', $charAfter) && !preg_match(RegexHelper::REGEX_PUNCTUATION, $charAfter));
     if ($character === '_') {
         $canOpen = $leftFlanking && (!$rightFlanking || preg_match(RegexHelper::REGEX_PUNCTUATION, $charBefore));
         $canClose = $rightFlanking && (!$leftFlanking || preg_match(RegexHelper::REGEX_PUNCTUATION, $charAfter));
     } else {
         $canOpen = $leftFlanking;
         $canClose = $rightFlanking;
     }
     $inlineContext->getInlines()->add(new Text($cursor->getPreviousText(), array('delim' => true)));
     // Add entry to stack to this opener
     $delimiter = new Delimiter($character, $numDelims, $inlineContext->getInlines()->count() - 1, $canOpen, $canClose);
     $inlineContext->getDelimiterStack()->push($delimiter);
     return true;
 }
 public function parse(InlineParserContext $inlineContext)
 {
     $cursor = $inlineContext->getCursor();
     if ($cursor->getFirstNonSpaceCharacter() !== '{') {
         return false;
     }
     $char = $cursor->getCharacter();
     if ('{' === $char) {
         $char = (string) $cursor->getCharacter($cursor->getPosition() - 1);
     }
     $attributes = AttributesUtils::parse($cursor);
     if (empty($attributes)) {
         return false;
     }
     if ('' === $char) {
         $cursor->advanceToFirstNonSpace();
     }
     $node = new InlineAttributes($attributes, ' ' === $char || '' === $char);
     $inlineContext->getContainer()->appendChild($node);
     $inlineContext->getDelimiterStack()->push(new Delimiter('attributes', 1, $node, false, false));
     return true;
 }
 /**
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(InlineParserContext $inlineContext)
 {
     $cursor = $inlineContext->getCursor();
     $character = $this->getCharacterType($cursor->getCharacter());
     $charBefore = $cursor->peek(-1);
     if ($charBefore === null) {
         $charBefore = "\n";
     }
     $cursor->advance();
     $charAfter = $cursor->getCharacter();
     if ($charAfter === null) {
         $charAfter = "\n";
     }
     list($leftFlanking, $rightFlanking) = $this->determineFlanking($charBefore, $charAfter);
     $canOpen = $leftFlanking && !$rightFlanking;
     $canClose = $rightFlanking;
     $node = new Text($character, ['delim' => true]);
     $inlineContext->getContainer()->appendChild($node);
     // Add entry to stack to this opener
     $inlineContext->getDelimiterStack()->push(new Delimiter($character, 1, $node, $canOpen, $canClose));
     return true;
 }
Esempio n. 29
0
 /**
  * @param ContextInterface    $context
  * @param InlineParserContext $inlineContext
  *
  * @return bool
  */
 public function parse(ContextInterface $context, InlineParserContext $inlineContext)
 {
     if ($inlineContext->getCursor()->getCharacter() !== '[') {
         return false;
     }
     $inlineContext->getCursor()->advance();
     $inlineContext->getInlines()->add(new Text('[', ['delim' => true]));
     // Add entry to stack for this opener
     $delimiter = new Delimiter('[', 1, $inlineContext->getInlines()->count() - 1, true, false, $inlineContext->getCursor()->getPosition());
     $inlineContext->getDelimiterStack()->push($delimiter);
     return true;
 }
 public function parse(InlineParserContext $inlineContext)
 {
     $cursor = $inlineContext->getCursor();
     // The @ symbol must not have any other characters immediately prior
     $previousChar = $cursor->peek(-1);
     if ($previousChar !== null && $previousChar !== ' ') {
         // peek() doesn't modify the cursor, so no need to restore state first
         return false;
     }
     // Save the cursor state in case we need to rewind and bail
     $previousState = $cursor->saveState();
     // Advance past the @ symbol to keep parsing simpler
     $cursor->advance();
     // Parse the handle
     $handle = $cursor->match('/^[A-Za-z0-9_]{1,15}(?!\\w)/');
     if (empty($handle)) {
         // Regex failed to match; this isn't a valid Twitter handle
         $cursor->restoreState($previousState);
         return false;
     }
     $profileUrl = 'https://twitter.com/' . $handle;
     $inlineContext->getContainer()->appendChild(new Link($profileUrl, '@' . $handle));
     return true;
 }