protected function setNewlinesAfterClosingTags($string, $tag, $newlineCount = 1, $selfClosing = false)
    {
        // Start of the pattern.
        $pattern = '/';

        if ($selfClosing) {
            // Find the self-closing tag, including its attributes and optionally a closing slash.
            // .*? means: Get any characters, 0 or more, but non-greedy so stop when the first / or > is encountered.
            $pattern .= '(<' . $tag . '.*?[\\/]?>)';
        } else {
            // Find the closing tag.
            $pattern .= '(<\\/' . $tag . '>)';
        }

        // Capture any newlines after the tag as well.
        $pattern .= '([\\n]*)';

        // End of the pattern. Use i to make it case-insensitive, as HTML tags can be both uppercase and lowercase.
        $pattern .= '/i';

        // Append all pattern matches with a newline character (or more if specified).
        $newlines = '';
        for ($i = 0; $i < $newlineCount; $i++) {
            $newlines .= PHP_EOL;
        }

        // Loop over all matching tags from the string.
        return preg_replace_callback($pattern, function ($match) use ($newlines) {
            // Return the tag appended by the specified amount of newlines. Note that $match[0] is the full captured
            // match, so it also includes the newlines after the tag. $match[1] is just the tag itself, and $match[2]
            // are the newlines following it (if any).
            return $match[1] . $newlines;
        }, $string);
    }