diff --git a/doc/BBCode.md b/doc/BBCode.md index 59f741449..08c43636f 100644 --- a/doc/BBCode.md +++ b/doc/BBCode.md @@ -633,6 +633,14 @@ On Mastodon this field is used for the content warning. @user@domain.tld #hashtag + + Additionally, [pre] blocks preserve spaces: + + +       Spaces + [nosmile] is used to disable smilies on a post by post basis

diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index 1cd8e438c..ba5bde045 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -1299,9 +1299,9 @@ class BBCode // Remove the abstract element. It is a non visible element. $text = self::stripAbstract($text); - // Move all spaces out of the tags - $text = preg_replace("/\[(\w*)\](\s*)/ism", '$2[$1]', $text); - $text = preg_replace("/(\s*)\[\/(\w*)\]/ism", '[/$2]$1', $text); + // Move new lines outside of tags + $text = preg_replace("#\[(\w*)](\n*)#ism", '$2[$1]', $text); + $text = preg_replace("#(\n*)\[/(\w*)]#ism", '[/$2]$1', $text); // Extract the private images which use data urls since preg has issues with // large data sizes. Stash them away while we do bbcode conversion, and then put them back @@ -1878,7 +1878,11 @@ class BBCode // Remove escaping tags $text = preg_replace("/\[noparse\](.*?)\[\/noparse\]/ism", '\1', $text); $text = preg_replace("/\[nobb\](.*?)\[\/nobb\]/ism", '\1', $text); - $text = preg_replace("/\[pre\](.*?)\[\/pre\]/ism", '\1', $text); + + // Additionally, [pre] tags preserve spaces + $text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", function ($match) { + return str_replace(' ', ' ', $match[1]); + }, $text); return $text; }); // Escaped code diff --git a/tests/src/Content/Text/BBCodeTest.php b/tests/src/Content/Text/BBCodeTest.php index 35dff87d9..77613e891 100644 --- a/tests/src/Content/Text/BBCodeTest.php +++ b/tests/src/Content/Text/BBCodeTest.php @@ -236,7 +236,15 @@ class BBCodeTest extends MockedTest 'bug-7808-code-amp' => [ 'expectedHtml' => '&', 'text' => '[code]&[/code]', - ] + ], + 'task-8800-pre-spaces-notag' => [ + 'expectedHtml' => '[test] Space', + 'text' => '[test] Space', + ], + 'task-8800-pre-spaces' => [ + 'expectedHtml' => '    Spaces', + 'text' => '[pre] Spaces[/pre]', + ], ]; }