class FilterAutoP

Same name and namespace in other branches
  1. 11.x core/modules/filter/src/Plugin/Filter/FilterAutoP.php \Drupal\filter\Plugin\Filter\FilterAutoP
  2. 10 core/modules/filter/src/Plugin/Filter/FilterAutoP.php \Drupal\filter\Plugin\Filter\FilterAutoP
  3. 9 core/modules/filter/src/Plugin/Filter/FilterAutoP.php \Drupal\filter\Plugin\Filter\FilterAutoP
  4. 8.9.x core/modules/filter/src/Plugin/Filter/FilterAutoP.php \Drupal\filter\Plugin\Filter\FilterAutoP

Provides a filter to convert line breaks to HTML.

Attributes

#[Filter(id: "filter_autop", title: new TranslatableMarkup("Convert line breaks into HTML (i.e. <code>&lt;br&gt;</code> and <code>&lt;p&gt;</code>)"), type: FilterInterface::TYPE_MARKUP_LANGUAGE)]

Hierarchy

Expanded class hierarchy of FilterAutoP

2 files declare their use of FilterAutoP
FilterKernelTest.php in core/modules/filter/tests/src/Kernel/FilterKernelTest.php
FundamentalCompatibilityConstraintValidator.php in core/modules/ckeditor5/src/Plugin/Validation/Constraint/FundamentalCompatibilityConstraintValidator.php

File

core/modules/filter/src/Plugin/Filter/FilterAutoP.php, line 14

Namespace

Drupal\filter\Plugin\Filter
View source
class FilterAutoP extends FilterBase {
  
  /**
   * {@inheritdoc}
   */
  public function process($text, $langcode) {
    // All block level tags.
    $block = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|option|form|map|area|blockquote|address|math|input|p|h[1-6]|fieldset|legend|hr|article|aside|details|figcaption|figure|footer|header|hgroup|menu|nav|section|summary)';
    // Split at opening and closing PRE, SCRIPT, STYLE, OBJECT, IFRAME tags and
    // comments. We don't apply any processing to the contents of these tags to
    // avoid messing up code. We look for matched pairs and allow basic nesting.
    // For example,
    // "processed<pre>ignored<script>ignored</script>ignored</pre>processed".
    $chunks = preg_split('@(<!--.*?-->|</?(?:pre|script|style|object|iframe|drupal-media|svg|!--)[^>]*>)@i', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
    // Note: PHP ensures the array consists of alternating delimiters and
    // literals and begins and ends with a literal (inserting NULL as required).
    $ignore = FALSE;
    $ignore_tag = '';
    $output = '';
    foreach ($chunks as $i => $chunk) {
      if ($i % 2) {
        if (str_starts_with($chunk, '<!--')) {
          // Nothing to do, this is a comment.
          $output .= $chunk;
          continue;
        }
        // Opening or closing tag?
        $open = $chunk[1] != '/';
        [$tag] = preg_split('/[ >]/', substr($chunk, 2 - $open), 2);
        if (!$ignore) {
          if ($open) {
            $ignore = TRUE;
            $ignore_tag = $tag;
          }
        }
        elseif (!$open && $ignore_tag == $tag) {
          $ignore = FALSE;
          $ignore_tag = '';
        }
      }
      elseif (!$ignore) {
        // Skip if the next chunk starts with Twig theme debug.
        // @see twig_render_template()
        if (isset($chunks[$i + 1]) && $chunks[$i + 1] === '<!-- THEME DEBUG -->') {
          $chunk = rtrim($chunk, "\n");
          $output .= $chunk;
          continue;
        }
        // Skip if the preceding chunk was the end of a Twig theme debug.
        // @see \Drupal\Core\Template\TwigThemeEngine::renderTemplate()
        if (isset($chunks[$i - 1])) {
          if (str_starts_with($chunks[$i - 1], '<!-- BEGIN OUTPUT from ') || str_starts_with($chunks[$i - 1], '<!-- 💡 BEGIN CUSTOM TEMPLATE OUTPUT from ')) {
            $chunk = ltrim($chunk, "\n");
            $output .= $chunk;
            continue;
          }
        }
        // Just to make things a little easier, pad the end.
        $chunk = preg_replace('|\\n*$|', '', $chunk) . "\n\n";
        $chunk = preg_replace('|<br />\\s*<br />|', "\n\n", $chunk);
        // Space things out a little.
        $chunk = preg_replace('!(<' . $block . '[^>]*>)!', "\n\$1", $chunk);
        // Space things out a little.
        $chunk = preg_replace('!(</' . $block . '>)!', "\$1\n\n", $chunk);
        // Take care of duplicates.
        $chunk = preg_replace("/\n\n+/", "\n\n", $chunk);
        $chunk = preg_replace('/^\\n|\\n\\s*\\n$/', '', $chunk);
        // Make paragraphs, including one at the end.
        $chunk = '<p>' . preg_replace('/\\n\\s*\\n\\n?(.)/', "</p>\n<p>\$1", $chunk) . "</p>\n";
        // Problem with nested lists.
        $chunk = preg_replace("|<p>(<li.+?)</p>|", "\$1", $chunk);
        $chunk = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote\$1><p>", $chunk);
        $chunk = str_replace('</blockquote></p>', '</p></blockquote>', $chunk);
        // Under certain strange conditions it could create a P of entirely
        // whitespace.
        $chunk = preg_replace('|<p>\\s*</p>\\n?|', '', $chunk);
        $chunk = preg_replace('!<p>\\s*(</?' . $block . '[^>]*>)!', "\$1", $chunk);
        $chunk = preg_replace('!(</?' . $block . '[^>]*>)\\s*</p>!', "\$1", $chunk);
        // Make line breaks.
        $chunk = preg_replace('|(?<!<br />)\\s*\\n|', "<br />\n", $chunk);
        $chunk = preg_replace('!(</?' . $block . '[^>]*>)\\s*<br />!', "\$1", $chunk);
        $chunk = preg_replace('!<br />(\\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)>)!', '$1', $chunk);
        $chunk = preg_replace('/&([^#])(?![A-Za-z0-9]{1,8};)/', '&amp;$1', $chunk);
      }
      $output .= $chunk;
    }
    return new FilterProcessResult($output);
  }
  
  /**
   * {@inheritdoc}
   */
  public function tips($long = FALSE) {
    if ($long) {
      return $this->t('Lines and paragraphs are automatically recognized. The &lt;br /&gt; line break, &lt;p&gt; paragraph and &lt;/p&gt; close paragraph tags are inserted automatically. If paragraphs are not recognized simply add a couple of blank lines.');
    }
    else {
      return $this->t('Lines and paragraphs break automatically.');
    }
  }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
AutowiredInstanceTrait::createInstanceAutowired public static function Instantiates a new instance of the implementing class using autowiring.
AutowiredInstanceTrait::getAutowireArguments private static function Resolves arguments for a method using autowiring.
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 2
DependencySerializationTrait::__wakeup public function 2
FilterAutoP::process public function Overrides FilterInterface::process
FilterAutoP::tips public function Overrides FilterBase::tips
FilterBase::$provider public property The name of the provider that owns this filter.
FilterBase::$settings public property An associative array containing the configured settings of this filter.
FilterBase::$status public property A Boolean indicating whether this filter is enabled.
FilterBase::$weight public property The weight of this filter compared to others in a filter collection.
FilterBase::calculateDependencies public function Overrides DependentPluginInterface::calculateDependencies 1
FilterBase::defaultConfiguration public function Overrides ConfigurableInterface::defaultConfiguration
FilterBase::getConfiguration public function Overrides ConfigurableInterface::getConfiguration
FilterBase::getDescription public function Overrides FilterInterface::getDescription
FilterBase::getHTMLRestrictions public function Overrides FilterInterface::getHTMLRestrictions 4
FilterBase::getLabel public function Overrides FilterInterface::getLabel
FilterBase::getType public function Overrides FilterInterface::getType
FilterBase::prepare public function Overrides FilterInterface::prepare
FilterBase::setConfiguration public function Overrides ConfigurableInterface::setConfiguration 1
FilterBase::settingsForm public function Overrides FilterInterface::settingsForm 3
FilterBase::__construct public function Overrides PluginBase::__construct 7
FilterInterface::TYPE_HTML_RESTRICTOR constant HTML tag and attribute restricting filters to prevent XSS attacks.
FilterInterface::TYPE_MARKUP_LANGUAGE constant Non-HTML markup language filters that generate HTML.
FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE constant Irreversible transformation filters.
FilterInterface::TYPE_TRANSFORM_REVERSIBLE constant Reversible transformation filters.
MessengerTrait::$messenger protected property The messenger. 26
MessengerTrait::messenger public function Gets the messenger. 26
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::create public static function Instantiates a new instance of the implementing class using autowiring. 68
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Overrides PluginInspectionInterface::getPluginDefinition 2
PluginBase::getPluginId public function Overrides PluginInspectionInterface::getPluginId
StringTranslationTrait::$stringTranslation protected property The string translation service. 3
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. 1

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.