You are here

class AtAutolinker in Markdown 3.0.x

Plugin annotation


@MarkdownExtension(
  id = "at_autolinker",
  label = @Translation("@ Autolinker"),
  installed = TRUE,
  description = @Translation("Automatically link commonly used references that come after an at character (@) without having to use the link syntax."),
  parsers = {"thephpleague/commonmark", "thephpleague/commonmark-gfm"},
)

Hierarchy

Expanded class hierarchy of AtAutolinker

File

src/Plugin/Markdown/Extension/AtAutolinker.php, line 22

Namespace

Drupal\markdown\Plugin\Markdown\Extension
View source
class AtAutolinker extends CommonMarkExtension implements InlineParserInterface, MarkdownGuidelinesAlterInterface {

  /**
   * {@inheritdoc}
   */
  public function alterGuidelines(array &$guides = []) {
    $user = \Drupal::currentUser();
    if ($user
      ->isAnonymous()) {
      $user = User::load(1);
    }
    if ($this
      ->getSetting('type') === 'user') {
      $description = [
        $this
          ->t('Text that starts with an at symbol (@) followed by any character other than a space will be automatically linked to users on this site.'),
      ];
      if ($this
        ->getSetting('format_username')) {
        $description[] = $this
          ->t('The formatted user name will be used in place of the text.');
      }
      $description[] = $this
        ->t('If the user does not exist, it will not automatically link.');
      $guides['links']['items'][] = [
        'title' => $this
          ->t('@ Autolinker'),
        'description' => $description,
        'tags' => [
          'a' => '@' . $user
            ->getAccountName(),
        ],
      ];
    }
    elseif ($this
      ->getSetting('type') === 'url') {
      $guides['links']['items'][] = [
        'title' => $this
          ->t('@ Autolinker'),
        'description' => $this
          ->t('Text that starts with an at symbol (@) followed by any character other than a space will automatically be linked to the following URL: <code>@url</code>', [
          '@url' => $this
            ->getSetting('url'),
        ]),
        'tags' => [
          'a' => [
            '@dries',
          ],
        ],
      ];
    }
  }

  /**
   * {@inheritdoc}
   */
  public function defaultSettings() {
    return [
      'type' => 'user',
      'format_username' => TRUE,
      'url' => 'https://www.drupal.org/u/[text]',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getCharacters() : array {
    return [
      '@',
    ];
  }

  /**
   * {@inheritdoc}
   */
  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 !== ' ') {

      // 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') {
      $users = \Drupal::entityTypeManager()
        ->getStorage('user');

      /** @var \Drupal\user\UserInterface $user */
      $user = is_numeric($text) ? $users
        ->load($text) : $users
        ->loadByProperties([
        'name' => $text,
      ]);
      if ($user && $user
        ->id()) {
        $url = $user
          ->toUrl('canonical', [
          'absolute' => TRUE,
        ])
          ->toString();
        $title = $this
          ->t('View user profile.');
        $text = $this
          ->getSetting('format_username') ? $user
          ->getDisplayName() : $user
          ->getAccountName();
      }
      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
      ->getContainer()
      ->appendChild(new Link($url, '@' . $text, $title));
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $element, FormStateInterface $formState, MarkdownFilterInterface $filter) {
    $element = parent::settingsForm($element, $formState, $filter);
    $selector = $this
      ->getSatesSelector($this
      ->getElementParents($element, [
      $this
        ->getPluginId(),
    ]), 'type');
    $element['type'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Map text to'),
      '#default_value' => $this
        ->getSetting('type'),
      '#options' => [
        'user' => $this
          ->t('User'),
        'url' => $this
          ->t('URL'),
      ],
    ];
    $element['format_username'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Replace username with formatted display name'),
      '#description' => $this
        ->t('If enabled, it will replace the matched text with the formatted username.'),
      '#default_value' => $this
        ->getSetting('format_username'),
      '#states' => [
        'visible' => [
          $selector => [
            'value' => 'user',
          ],
        ],
      ],
    ];
    $element['url'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('URL'),
      '#description' => $this
        ->t('A URL to format text with. Use the token "[text]" where it is needed. If you need to include the @, use the URL encoded equivalent: <code>%40</code>. Example: <code>https://twitter.com/search?q=%40[text]</code>.'),
      '#default_value' => $this
        ->getSetting('url'),
      '#states' => [
        'visible' => [
          $selector => [
            'value' => 'url',
          ],
        ],
      ],
    ];
    return $element;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
AtAutolinker::alterGuidelines public function Alters existing guides on how to use the Markdown Parser. Overrides MarkdownGuidelinesAlterInterface::alterGuidelines
AtAutolinker::defaultSettings public function Retrieves the default settings. Overrides BaseExtension::defaultSettings
AtAutolinker::getCharacters public function
AtAutolinker::parse public function
AtAutolinker::settingsForm public function Returns the configuration form elements specific to this plugin. Overrides BaseExtension::settingsForm
BaseExtension::baseConfigurationDefaults protected function Returns generic default configuration for markdown extension plugins.
BaseExtension::calculateDependencies public function
BaseExtension::defaultConfiguration public function
BaseExtension::getConfiguration public function
BaseExtension::getDescription public function Retrieves the description of the plugin, if set. Overrides MarkdownInstallablePluginInterface::getDescription
BaseExtension::getLabel public function Displays the human-readable label of the plugin. Overrides MarkdownInstallablePluginInterface::getLabel
BaseExtension::getSetting public function Retrieves a setting. Overrides MarkdownExtensionInterface::getSetting
BaseExtension::getSettings public function Retrieves the current settings. Overrides MarkdownExtensionInterface::getSettings
BaseExtension::getUrl public function Retrieves the URL of the plugin, if set. Overrides MarkdownInstallablePluginInterface::getUrl
BaseExtension::getVersion public function The current version of the parser. Overrides MarkdownInstallablePluginInterface::getVersion
BaseExtension::installed public static function Indicates whether the parser is installed. Overrides MarkdownInstallablePluginInterface::installed
BaseExtension::isEnabled public function Indicates whether the extension is being used. Overrides MarkdownExtensionInterface::isEnabled
BaseExtension::isInstalled public function Indicates whether the parser is installed. Overrides MarkdownInstallablePluginInterface::isInstalled
BaseExtension::label public function
BaseExtension::setConfiguration public function
BaseExtension::setSetting public function Sets a specific setting. Overrides MarkdownExtensionInterface::setSetting
BaseExtension::setSettings public function Provides settings to an extension. Overrides MarkdownExtensionInterface::setSettings
BaseExtension::version public static function Retrieves the version of the installed parser. Overrides MarkdownInstallablePluginInterface::version
BaseExtension::__construct public function Constructs a \Drupal\Component\Plugin\PluginBase object. Overrides PluginBase::__construct
CommonMarkExtension::getName public function Retrieves the name of the extension. Overrides CommonMarkExtensionInterface::getName
DependencySerializationTrait::$_entityStorages protected property
DependencySerializationTrait::$_serviceIds protected property
DependencySerializationTrait::__sleep public function 2
DependencySerializationTrait::__wakeup public function 2
MarkdownStatesTrait::getElementParents protected static function Retrieves the ancestry of the extension in a form/render array.
MarkdownStatesTrait::getSatesSelector protected static function Retrieves a states selector to use based on the form/render array parents.
MessengerTrait::$messenger protected property The messenger. 27
MessengerTrait::messenger public function Gets the messenger. 27
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 2
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
StringTranslationTrait::$stringTranslation protected property The string translation service. 4
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.