New Lines to Paragraph Tags (nl2p)

Problem: Emails from your site go out in a good looking HTML format, but some of the content you want to inject in those emails are plain text while others are already formatted with HTML. The email content of the plain text emails which are only plain text now appear as one big block of text with no line breaks.

Let's look at this problem specifically in the context of a Drupal website.

All the emails such as welcome, password recover, etc... are plain text by default. Now you want to add a nice email template utilizing a module like mimemail.

The mimemail template is overridden with your fancy HTML/CSS wrapper around the body but you notice that there are no line breaks because they do not render in HTML.

There are a few options here:

1) Re-format all the emails with HTML by either wrapping your paragraphs in 'p' tags, or adding 'br' tags.

2) Using an input filter that converts new lines to 'br' tags and assigning that filter in mimemail. (easily done through the UI)

3) Running the body of the email through a function that adds paragraph tags where new lines are detected, only if HTML is not detected already.

I think any of those are acceptable choices, but I went about this recently with option 3. The reasoning was because I didn't want to reformat all site emails to HTML, and I didn't want to be concerned with the default format of any future emails added by developers or contrib modules.

In order for this to work, we need to be able to send HTML and non HTML into this function. If HTML is detected, then it is assumed that this is already an HTML formatted body and we don't need to do anything. If HTML is not detected, then the job is to add paragraph tags around every double line break, and 'br' tag with every single line break.

Here is a solution:

<?php
function mytheme_nl2p($string, $only_if_no_html = TRUE) {
  // Replace the input string by default unless we find a reason not to.
  $replace = TRUE;

  // If the only_if_no_html flag is set, then we only want to replace if no HTML is detected
  if ($only_if_no_html) {
    // Create a string of the input string with stripped tags
    $str2 = strip_tags($string);

    // If there is a difference, then HTML must have been in the input string.
    // Since HTML already exists, we do not want to replace new lines with HTML
    if ($str2 != $string) {
      $replace = FALSE;
    }
  }

  // Now return the replacement string if we are supposed to replace it.
  if ($replace) {
    return
      '<p>'
      .preg_replace('#(<br\s*?/?>\s*?){2,}#', '</p>'."\n".'<p>', nl2br($string))
      .'</p>';
  }

  // Otherwise, we just return the input string.
  return $string;
}