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);
}
}
