You are here

public function HashAutolinker::parse in Markdown 3.0.x

File

src/Plugin/Markdown/Extension/HashAutolinker.php, line 85

Class

HashAutolinker
Plugin annotation @MarkdownExtension( id = "hash_autolinker", label = @Translation("# Autolinker"), installed = TRUE, description = @Translation("Automatically link commonly used references that come after a hash character (#) without having…

Namespace

Drupal\markdown\Plugin\Markdown\Extension

Code

public function parse(InlineParserContext $inline_context) : bool {
  $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');

  // @todo Make entity type abstract and comment aware.
  if ($type === 'node' && is_numeric($text) && ($node = \Drupal::entityTypeManager()
    ->getStorage('node')
    ->load($text))) {
    $url = $node
      ->toUrl('canonical', [
      'absolute' => TRUE,
    ])
      ->toString();
    if ($this
      ->getSetting('node_title') && ($title = $node
      ->label())) {
      $text = $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
    ->getContainer()
    ->appendChild(new Link($url, $text, $title));
  return TRUE;
}