You are here

abstract class BaseParser in Markdown 8.2

Same name and namespace in other branches
  1. 3.0.x src/Plugin/Markdown/BaseParser.php \Drupal\markdown\Plugin\Markdown\BaseParser

Base class form Markdown Parser instances.

@property \Drupal\markdown\Annotation\MarkdownParser $pluginDefinition @method \Drupal\markdown\Annotation\MarkdownParser getPluginDefinition()

Hierarchy

Expanded class hierarchy of BaseParser

3 files declare their use of BaseParser
Cmark.php in src/Plugin/Markdown/Pecl/Cmark.php
Parsedown.php in src/Plugin/Markdown/Parsedown/Parsedown.php
PhpMarkdown.php in src/Plugin/Markdown/PhpMarkdown/PhpMarkdown.php
1 string reference to 'BaseParser'
markdown.data_types.schema.yml in config/schema/markdown.data_types.schema.yml
config/schema/markdown.data_types.schema.yml

File

src/Plugin/Markdown/BaseParser.php, line 31

Namespace

Drupal\markdown\Plugin\Markdown
View source
abstract class BaseParser extends InstallablePluginBase implements FilterAwareInterface, ParserInterface, PluginFormInterface {
  use EnabledPluginTrait;
  use FilterAwareTrait;
  use RefinableCacheableDependencyTrait;
  use SettingsTrait;

  /**
   * {@inheritdoc}
   */
  protected $enabled = TRUE;

  /**
   * Validates parser settings.
   *
   * @param array $settings
   *   The parser settings to validate.
   * @param \Symfony\Component\Validator\Context\ExecutionContextInterface $context
   *   The validation execution context.
   */
  public static function validateSettings(array $settings, ExecutionContextInterface $context) {
    try {
      $object = $context
        ->getObject();
      $parent = $object instanceof Mapping ? $object
        ->getParent() : NULL;
      $parserId = $parent instanceof Mapping && ($id = $parent
        ->get('id')) ? $id
        ->getValue() : NULL;
      $parserManager = ParserManager::create();
      if (!$parserId || !$parserManager
        ->hasDefinition($parserId)) {
        throw new \RuntimeException(sprintf('Unknown markdown parser: "%s"', $parserId));
      }
      $parser = $parserManager
        ->createInstance($parserId);

      // Immediately return if parser doesn't have any settings.
      if (!$parser instanceof SettingsInterface) {
        return;
      }
      $defaultSettings = $parser::defaultSettings($parser
        ->getPluginDefinition());
      $unknownSettings = array_keys(array_diff_key($settings, $defaultSettings));
      if ($unknownSettings) {
        throw new \RuntimeException(sprintf('Unknown parser settings: %s', implode(', ', $unknownSettings)));
      }
    } catch (\RuntimeException $exception) {
      $context
        ->addViolation($exception
        ->getMessage());
    }
  }

  /**
   * Converts Markdown into HTML.
   *
   * Note: this method is not guaranteed to be safe from XSS attacks. This
   * returns the raw output from the parser itself.
   *
   * If you need to render this output you should use the
   * \Drupal\markdown\Plugin\Markdown\MarkdownParserInterface::parse()
   * method instead.
   *
   * @param string $markdown
   *   The markdown string to convert.
   * @param \Drupal\Core\Language\LanguageInterface $language
   *   Optional. The language of the text that is being converted.
   *
   * @return string
   *   The raw parsed HTML returned from the parser.
   *
   * @see \Drupal\markdown\Render\ParsedMarkdownInterface
   * @see \Drupal\markdown\Plugin\Markdown\ParserInterface::parse()
   *
   * @internal
   */
  protected abstract function convertToHtml($markdown, LanguageInterface $language = NULL);

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    return $form;
  }

  /**
   * {@inheritdoc}
   *
   * @deprecated in markdown:8.x-2.0 and is removed from markdown:3.0.0.
   *   Use RenderStrategyInterface::getCustomAllowedHtml instead.
   * @see https://www.drupal.org/project/markdown/issues/3142418
   */
  public function getAllowedHtml() {
    return $this
      ->getCustomAllowedHtml();
  }

  /**
   * {@inheritdoc}
   */
  public function getAllowedHtmlPlugins() {
    return $this
      ->config()
      ->get('render_strategy.plugins') ?: [];
  }

  /**
   * {@inheritdoc}
   */
  public function getConfiguration() {
    $configuration = parent::getConfiguration();
    $configuration['render_strategy'] = [
      'type' => $this
        ->getRenderStrategy(),
      'custom_allowed_html' => $this
        ->getCustomAllowedHtml(),
      'plugins' => $this
        ->getAllowedHtmlPlugins(),
    ];
    ksort($configuration['render_strategy']['plugins']);
    return $configuration;
  }

  /**
   * {@inheritdoc}
   */
  protected function getConfigurationSortOrder() {
    return [
      'render_strategy' => -11,
    ] + parent::getConfigurationSortOrder();
  }

  /**
   * Builds context around a markdown parser's hierarchy filter format chain.
   *
   * @param array $context
   *   Additional context to pass.
   *
   * @return array
   *   The context, including references to various parser and filter instances.
   */
  protected function getContext(array $context = []) {
    $parser = NULL;
    if ($this instanceof ParserAwareInterface) {
      $parser = $this
        ->getParser();
    }
    elseif ($this instanceof ParserInterface) {
      $parser = $this;
    }
    $filter = NULL;
    if ($this instanceof FilterAwareInterface) {
      $filter = $this
        ->getFilter();
    }
    elseif ($parser instanceof FilterAwareInterface) {
      $filter = $parser
        ->getFilter();
    }
    elseif ($this instanceof FilterInterface) {
      $filter = $this;
    }
    $format = NULL;
    if ($this instanceof FilterFormatAwareInterface) {
      $format = $this
        ->getFilterFormat();
    }
    elseif ($parser instanceof FilterFormatAwareInterface) {
      $format = $parser
        ->getFilterFormat();
    }
    elseif ($filter instanceof FilterFormatAwareInterface) {
      $format = $filter
        ->getFilterFormat();
    }
    elseif ($this instanceof FilterFormat) {
      $format = $this;
    }
    return [
      'parser' => $parser,
      'filter' => $filter,
      'format' => $format,
    ] + $context;
  }

  /**
   * {@inheritdoc}
   */
  public function getCustomAllowedHtml() {
    return $this
      ->config()
      ->get('render_strategy.custom_allowed_html');
  }

  /**
   * {@inheritdoc}
   */
  public function getRenderStrategy() {
    return $this
      ->config()
      ->get('render_strategy.type') ?: static::FILTER_OUTPUT;
  }

  /**
   * {@inheritdoc}
   */
  public function parse($markdown, LanguageInterface $language = NULL) {
    $moduleHandler = \Drupal::moduleHandler();
    $renderStrategy = $this
      ->getRenderStrategy();
    if ($renderStrategy === static::ESCAPE_INPUT) {
      $markdown = Html::escape($markdown);
    }
    elseif ($renderStrategy === static::STRIP_INPUT) {
      $markdown = strip_tags($markdown);
    }

    // Invoke hook_markdown_alter().
    $context = $this
      ->getContext([
      'language' => $language,
    ]);
    $moduleHandler
      ->alter('markdown', $markdown, $context);

    // Convert markdown to HTML.
    $html = $this
      ->convertToHtml($markdown, $language);

    // Invoke hook_markdown_html_alter().
    $context['markdown'] = $markdown;
    $moduleHandler
      ->alter('markdown_html', $html, $context);

    // Filter all HTML output.
    if ($renderStrategy === static::FILTER_OUTPUT) {
      $html = (string) FilterHtml::fromParser($this)
        ->process($html, $language ? $language
        ->getId() : NULL);
    }
    return ParsedMarkdown::create($markdown, $html, $language)
      ->addCacheableDependency($this);
  }

  /**
   * A description explaining why a setting is disabled due to render strategy.
   *
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current form state.
   *
   * @return \Drupal\Component\Render\MarkupInterface
   *   The rendered description.
   */
  protected function renderStrategyDisabledSetting(FormStateInterface $form_state) {

    /** @var \Drupal\markdown\Form\SubformStateInterface $form_state */
    $markdownParents = $form_state
      ->get('markdownSubformParents');
    $parents = array_merge($markdownParents, [
      'render_strategy',
      'type',
    ]);
    $selector = ':input[name="' . array_shift($parents) . '[' . implode('][', $parents) . ']"]';

    /** @var \Drupal\markdown\Form\SubformStateInterface $form_state */
    return new FormattableMarkup('@disabled@warning', [
      '@disabled' => $form_state
        ->conditionalElement([
        '#type' => 'container',
        '#attributes' => [
          'class' => [
            'form-item--description',
            'is-disabled',
          ],
        ],
        [
          '#markup' => $this
            ->moreInfo($this
            ->t('<strong>NOTE:</strong> This setting is disabled when a render strategy is being used.'), RenderStrategyInterface::DOCUMENTATION_URL),
        ],
      ], 'visible', $selector, [
        '!value' => static::NONE,
      ]),
      '@warning' => $form_state
        ->conditionalElement([
        '#type' => 'container',
        '#theme_wrappers' => [
          'container__markdown_disabled_setting__render_strategy__warning',
        ],
        '#attributes' => [
          'class' => [
            'form-item__error-message',
            'form-item--error-message',
          ],
        ],
        [
          '#markup' => $this
            ->moreInfo($this
            ->t('<strong>WARNING:</strong> This setting does not guarantee protection against malicious JavaScript from being injected. It is recommended to use the "Filter Output" render strategy.'), RenderStrategyInterface::DOCUMENTATION_URL),
        ],
      ], 'visible', $selector, [
        'value' => static::NONE,
      ]),
    ]);
  }

  /**
   * Adds a conditional state for a setting element based on render strategy.
   *
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current form state.
   * @param array $element
   *   The element to modify, passed by reference.
   * @param string|string[] $state
   *   Optional. Additional states to trigger when setting is disabled, e.g.
   *   unchecked, etc.
   * @param array $conditions
   *   The conditions for which to trigger the state(s).
   */
  protected function renderStrategyDisabledSettingState(FormStateInterface $form_state, array &$element, $state = 'disabled', array $conditions = [
    '!value' => self::NONE,
  ]) {

    /** @var \Drupal\markdown\Form\SubformStateInterface $form_state */
    $markdownParents = $form_state
      ->get('markdownSubformParents');
    $parents = array_merge($markdownParents, [
      'render_strategy',
      'type',
    ]);
    $selector = ':input[name="' . array_shift($parents) . '[' . implode('][', $parents) . ']"]';
    $states = (array) $state;
    foreach ($states as $state) {
      $form_state
        ->addElementState($element, $state, $selector, $conditions);
    }

    // Add a conditional description explaining why the setting is disabled.
    if (!isset($element['#description'])) {
      $element['#description'] = $this
        ->renderStrategyDisabledSetting($form_state);
    }
    else {
      $element['#description'] = new FormattableMarkup('@description @renderStrategyDisabledSetting', [
        '@description' => $element['#description'],
        '@renderStrategyDisabledSetting' => $this
          ->renderStrategyDisabledSetting($form_state),
      ]);
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
AnnotatedPluginBase::$originalPluginId protected property The original plugin_id that was called, not a fallback identifier.
AnnotatedPluginBase::create public static function Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface::create
AnnotatedPluginBase::getConfigurationOverrides public function Retrieves the configuration overrides for the plugin. Overrides AnnotatedPluginInterface::getConfigurationOverrides
AnnotatedPluginBase::getDescription public function Retrieves the description of the plugin, if set. Overrides AnnotatedPluginInterface::getDescription
AnnotatedPluginBase::getOriginalPluginId public function Retrieves the original plugin identifier. Overrides AnnotatedPluginInterface::getOriginalPluginId
AnnotatedPluginBase::getProvider public function Returns the provider (extension name) of the plugin. Overrides AnnotatedPluginInterface::getProvider
AnnotatedPluginBase::getWeight public function Returns the weight of the plugin (used for sorting). Overrides AnnotatedPluginInterface::getWeight
AnnotatedPluginBase::__construct public function Constructs a \Drupal\Component\Plugin\PluginBase object. Overrides PluginBase::__construct
AnnotatedPluginBase::__toString public function
BaseParser::$enabled protected property
BaseParser::buildConfigurationForm public function Form constructor. Overrides PluginFormInterface::buildConfigurationForm 3
BaseParser::convertToHtml abstract protected function Converts Markdown into HTML. 4
BaseParser::getAllowedHtml Deprecated public function Overrides RenderStrategyInterface::getAllowedHtml
BaseParser::getAllowedHtmlPlugins public function Retrieves the allowed HTML plugins relevant to the object. Overrides RenderStrategyInterface::getAllowedHtmlPlugins
BaseParser::getConfiguration public function Gets this plugin's configuration. Overrides InstallablePluginBase::getConfiguration 2
BaseParser::getConfigurationSortOrder protected function Determines the configuration sort order by weight. Overrides InstallablePluginBase::getConfigurationSortOrder 1
BaseParser::getContext protected function Builds context around a markdown parser's hierarchy filter format chain.
BaseParser::getCustomAllowedHtml public function Retrieves the custom (user provided) allowed HTML. Overrides RenderStrategyInterface::getCustomAllowedHtml
BaseParser::getRenderStrategy public function Retrieves the render strategy to use. Overrides RenderStrategyInterface::getRenderStrategy
BaseParser::parse public function Parses markdown into HTML. Overrides ParserInterface::parse
BaseParser::renderStrategyDisabledSetting protected function A description explaining why a setting is disabled due to render strategy.
BaseParser::renderStrategyDisabledSettingState protected function Adds a conditional state for a setting element based on render strategy.
BaseParser::validateSettings public static function Validates parser settings.
CacheableDependencyTrait::$cacheContexts protected property Cache contexts.
CacheableDependencyTrait::$cacheMaxAge protected property Cache max-age.
CacheableDependencyTrait::$cacheTags protected property Cache tags.
CacheableDependencyTrait::getCacheContexts public function 3
CacheableDependencyTrait::getCacheMaxAge public function 3
CacheableDependencyTrait::getCacheTags public function 3
CacheableDependencyTrait::setCacheability protected function Sets cacheability; useful for value object constructors.
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
DependencyTrait::$dependencies protected property The object's dependencies.
DependencyTrait::addDependencies protected function Adds multiple dependencies.
DependencyTrait::addDependency protected function Adds a dependency.
EnabledPluginTrait::enabledByDefault public function 1
EnabledPluginTrait::isEnabled public function
FilterAwareTrait::$filter protected property A Filter plugin.
FilterAwareTrait::getFilter public function
FilterAwareTrait::setFilter public function
InstallablePluginBase::$config protected property The config for this plugin.
InstallablePluginBase::buildLibrary public function Builds a display for a library. Overrides InstallablePluginInterface::buildLibrary
InstallablePluginBase::buildStatus public function Builds a display status based on the current state of the plugin. Overrides InstallablePluginInterface::buildStatus
InstallablePluginBase::calculateDependencies public function Calculates dependencies for the configured plugin. Overrides DependentPluginInterface::calculateDependencies
InstallablePluginBase::config public function Retrieves the config instance for this plugin. Overrides InstallablePluginInterface::config
InstallablePluginBase::createConfig protected static function
InstallablePluginBase::defaultConfiguration public function Gets default configuration for this plugin. Overrides AnnotatedPluginBase::defaultConfiguration 1
InstallablePluginBase::getAvailableInstalls public function Retrieves available installs.
InstallablePluginBase::getConfigurationName protected function Returns the configuration name for the plugin.
InstallablePluginBase::getContainer public function Retrieves the container.
InstallablePluginBase::getDeprecated public function Retrieves the deprecation message, if any. Overrides InstallablePluginInterface::getDeprecated
InstallablePluginBase::getExperimental public function Retrieves the experimental message. Overrides InstallablePluginInterface::getExperimental
InstallablePluginBase::getInstalledId public function Retrieves the composer package name of the installable library, if any. Overrides InstallablePluginInterface::getInstalledId
InstallablePluginBase::getInstalledLibrary public function Retrieves the installed library used by the plugin. Overrides InstallablePluginInterface::getInstalledLibrary
InstallablePluginBase::getLabel public function Displays the human-readable label of the plugin. Overrides AnnotatedPluginBase::getLabel
InstallablePluginBase::getLink public function Retrieves the plugin as a link using its label and URL. Overrides InstallablePluginInterface::getLink
InstallablePluginBase::getObject public function @TODO: Refactor to use variadic parameters. Overrides InstallablePluginInterface::getObject
InstallablePluginBase::getObjectClass public function Retrieves the class name of the object defined by the installed library. Overrides InstallablePluginInterface::getObjectClass
InstallablePluginBase::getPluginDependencies protected function 1
InstallablePluginBase::getPreferredLibrary public function Retrieves the preferred library of the plugin. Overrides InstallablePluginInterface::getPreferredLibrary
InstallablePluginBase::getSortedConfiguration public function Retrieves the configuration for the plugin, but sorted. Overrides InstallablePluginInterface::getSortedConfiguration
InstallablePluginBase::getUrl public function Retrieves the URL of the plugin, if set. Overrides InstallablePluginInterface::getUrl
InstallablePluginBase::getVersion public function The current version of the plugin. Overrides InstallablePluginInterface::getVersion
InstallablePluginBase::getVersionConstraint public function
InstallablePluginBase::hasMultipleLibraries public function Indicates whether plugin has multiple installs to check. Overrides InstallablePluginInterface::hasMultipleLibraries
InstallablePluginBase::isInstalled public function Indicates whether the plugin is installed. Overrides InstallablePluginInterface::isInstalled
InstallablePluginBase::isPreferred public function Indicates whether the plugin is using the preferred library. Overrides InstallablePluginInterface::isPreferred
InstallablePluginBase::isPreferredLibraryInstalled public function Indicates whether the preferred library is installed. Overrides InstallablePluginInterface::isPreferredLibraryInstalled
InstallablePluginBase::setConfiguration public function Sets the configuration for this plugin instance. Overrides AnnotatedPluginBase::setConfiguration 3
InstallablePluginBase::showInUi public function Indicates whether the plugin should be shown in the UI. Overrides InstallablePluginInterface::showInUi
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
MoreInfoTrait::moreInfo protected function Appends existing content with a "More Info" link.
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 3
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.
PluginDependencyTrait::calculatePluginDependencies protected function Calculates and adds dependencies of a specific plugin instance.
PluginDependencyTrait::getPluginDependencies protected function Calculates and returns dependencies of a specific plugin instance. Aliased as: getPluginDependenciesTrait
PluginDependencyTrait::moduleHandler protected function Wraps the module handler.
PluginDependencyTrait::themeHandler protected function Wraps the theme handler.
RefinableCacheableDependencyTrait::addCacheableDependency public function 1
RefinableCacheableDependencyTrait::addCacheContexts public function
RefinableCacheableDependencyTrait::addCacheTags public function
RefinableCacheableDependencyTrait::mergeCacheMaxAge public function
RendererTrait::$renderer protected static property The Renderer service.
RendererTrait::renderer protected function Retrieves the Renderer service.
RenderStrategyInterface::DOCUMENTATION_URL constant The documentation URL for further explaining render strategies.
RenderStrategyInterface::ESCAPE_INPUT constant Strategy used to escape HTML input prior to parsing markdown.
RenderStrategyInterface::FILTER_OUTPUT constant Strategy used to filter the output of parsed markdown.
RenderStrategyInterface::MARKDOWN_XSS_URL Deprecated constant The URL for explaining Markdown and XSS; render strategies.
RenderStrategyInterface::NONE constant No render strategy.
RenderStrategyInterface::STRIP_INPUT constant Strategy used to remove HTML input prior to parsing markdown.
SettingsTrait::createSettingElement protected function Creates a setting element.
SettingsTrait::defaultSettings public static function 9
SettingsTrait::getDefaultSetting public function
SettingsTrait::getSetting public function
SettingsTrait::getSettingOverrides public function
SettingsTrait::getSettings public function
SettingsTrait::settingExists public function 2
SettingsTrait::settingsKey public function 6
SettingsTrait::submitConfigurationForm public function
SettingsTrait::validateConfigurationForm public function 2
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
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.