migrate_spip-1.0.0/src/Plugin/SpipRichText/Paragrapher.php

src/Plugin/SpipRichText/Paragrapher.php
<?php

declare(strict_types=1);

namespace Drupal\migrate_spip\Plugin\SpipRichText;

use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\migrate_spip\Attribute\SpipRichText;
use Drupal\migrate_spip\SpipRichTextBase;

/**
 * Manage paragraphs.
 */
#[SpipRichText(
  id: 'paragrapher',
  label: new TranslatableMarkup('Paragrapher'),
  weight: 0,
)]
final class Paragrapher extends SpipRichTextBase {

  /**
   * {@inheritdoc}
   */
  public function apply(string $text): string {
    $text = preg_replace(
      [
        // Prevent block html tag wrapped with a link.
        "#<p>(<a[^>]+><(?:" . self::HTML_TAGS_BLOCK . ")[^>]*>)\s*?#UimS",
        "#(?!</p>)(<a[^>]+><(?:h2|h3)[^>]*>)\s*?#UimS",
        // Add paragraph after block html tag (after link if there is one).
        "#</(?:" . self::HTML_TAGS_BLOCK . ")[^>]*>(?:</a>)*?\s*?#UimS",
        "#^.*$#msS",
        "#</?p\b\s?(.*?)>#iS",
        "#\s*<STOP P>$#",
      ],
      [
        '<STOP P>$1',
        '<STOP P>$1',
        '$0<p>',
        '<p>$0<STOP P>',
        '<STOP P><p $1>',
        '</p>',
      ],
      $text
    );

    $text = $this->closeParagraphManually($text);

    // Remove almost empty paragraphs.
    $text = preg_replace(
      [
        // Remove almost empty paragraphs.
        "#<p [^>]*>(<(?:/\w+|\w+[^>]*[^/])>)</p>#S",
        // Remove empty paragraphs.
        "#<p [^>]*>\s*</p>\s*#S",
        // Clean paragraph declarations.
        "#\n<p(.*)>#S",
        "#<p(\s+)>#S",
        "#^</p>#S",
        "#<p>$#S",
      ],
      [
        '',
        '',
        '$0',
        '<p>',
        '',
        '',
      ],
      $text
    );

    $text = str_replace(
      [
        // Removal of remaining potentials.
        '<STOP P>',
        // Specific cases with "<pre><code>" tag.
        '<p><pre><code>',
        "</code></p>\n</pre>",
      ],
      [
        '',
        '<pre><code>',
        '</code></pre>',
      ],
      $text
    );

    return trim($text);
  }

  /**
   * Closing paragraphs still open other than by a regex.
   *
   * @param string $text
   *   The text to process.
   *
   * @return string
   *   The process text.
   *
   * @see https://github.com/spip/textwheel/blob/2.0/wheels/spip/spip-paragrapher.php
   * @see fermer_para_mano()
   *
   * @SuppressWarnings(PHPMD.ElseExpression)
   * @SuppressWarnings(PHPMD.ShortVariable)
   */
  private function closeParagraphManually(string $text): string {
    $cut = '<p';
    $close = "</p>\n";

    if (str_contains($text, $cut) !== FALSE) {
      foreach (explode($cut, $text) as $c => $p) {
        if ($c == 0) {
          $text = $p;
        }
        else {
          $pi = strtolower($p);
          if (
            preg_match(
              ',</?(?:stop p|' . self::HTML_TAGS_BLOCK . ")\b,iS",
              $pi,
              $matches
            )
          ) {
            $pos = strpos($pi, (string) $matches[0]);
            $text .= $cut . str_replace(
                "\n",
                self::AUTOBR . "\n",
                rtrim(substr($p, 0, $pos))
              ) . $close . substr($p, $pos);
          }
          else {
            $text .= $cut . $p;
          }
        }
      }
    }

    $text = str_replace(self::AUTOBR . "\n<br", "\n<br", $text);
    $reg = ',(<(p|br|li)\b[^>]*>\s*)' . preg_quote(self::AUTOBR . "\n", ',') . ',iS';
    return preg_replace($reg, "\1\n", $text);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc