You are here

public function TocFilter::process in TOC filter 8.2

Performs the filter processing.

Parameters

string $text: The text string to be filtered.

string $langcode: The language code of the text to be filtered.

Return value

\Drupal\filter\FilterProcessResult The filtered text, wrapped in a FilterProcessResult object, and possibly with associated assets, cacheability metadata and placeholders.

Overrides FilterInterface::process

See also

\Drupal\filter\FilterProcessResult

File

src/Plugin/Filter/TocFilter.php, line 85
Contains \Drupal\toc_filter\Plugin\Filter\TocFilter.

Class

TocFilter
Provides a filter to display a table of contents.

Namespace

Drupal\toc_filter\Plugin\Filter

Code

public function process($text, $langcode) {
  $result = new FilterProcessResult($text);

  // If no [toc] is found, see if [toc] can be automatically added, else
  // return.
  if (stripos($text, '[toc') === FALSE) {
    switch ($this->settings['auto']) {
      case 'top':
        $text = '[toc]' . $text;
        break;
      case 'bottom':
        $text .= '[toc]';
        break;
      case '':
      default:
        return $result;
    }
  }

  // Remove block tags around token.
  $text = preg_replace('#<(p|div|h\\d|blockquote)[^>]*>\\s*(\\[toc[^]]*\\])\\s*</\\1>#', '\\2', $text);

  // Get custom options.
  if ($this->settings['type'] && ($toc_type = TocType::load($this->settings['type']))) {
    $toc_type_options = $toc_type
      ->getOptions() ?: [];
    $result
      ->addCacheableDependency($toc_type);
  }
  else {
    $toc_type_options = [];
  }

  // Replace first [toc] token and update the content.
  if (!preg_match('#\\[toc([^]]*)?\\]#is', $text, $match)) {
    return $result;
  }

  // Remove the [toc] token for the processed text.
  // This makes it easier to just return the original text.
  $result
    ->setProcessedText(str_replace($match[0], '', $text));

  // Parse inline options (aka attributes).
  $inline_options = self::parseOptions($match[1]);

  // Add custom setting to inline options.
  $inline_options += [
    'block' => $this->settings['block'],
  ];

  // Merge with default, global, filter, and inline options.
  $options = NestedArray::mergeDeepArray([
    $toc_type_options,
    $inline_options,
  ]);

  // Allow TOC filter options to be altered and optionally set to FALSE,
  // which will block a table of contents from being added.
  \Drupal::moduleHandler()
    ->alter('toc_filter', $text, $options);

  // If $option is FALSE, then just return the unprocessed result w/o
  // the [toc] token.
  if ($options === FALSE) {
    return $result;
  }

  /** @var \Drupal\toc_api\TocManagerInterface $toc_manager */
  $toc_manager = \Drupal::service('toc_api.manager');

  /** @var \Drupal\toc_api\TocBuilderInterface $toc_builder */
  $toc_builder = \Drupal::service('toc_api.builder');

  /** @var \Drupal\toc_api\TocInterface $toc */
  $toc = $toc_manager
    ->create('toc_filter', $text, $options);

  // If table of content is not visible, return the unprocessed result w/o
  // the [toc] token.
  if (!$toc
    ->isVisible()) {
    return $result;
  }

  // Replace the text with the render the content.
  $text = '<div class="toc-filter">' . $toc_builder
    ->renderContent($toc) . '</div>';

  // If block remove [toc] token, else replace it with the rendered TOC.
  if ($toc
    ->isBlock()) {
    $text = str_replace($match[0], '', $text);
  }
  else {
    $text = str_replace($match[0], $toc_builder
      ->renderToc($toc), $text);
  }
  return $result
    ->setProcessedText($text);
}