I have an AngularJs + Rails.
I have a form with a text field where the user can write whatever text with break lines. When the user submits the form the message stored in db and sent by email to another user. The email sent should keep the line breaks.
The point is the format of the message is working perfectly in production. However it has stopped working in development. Aparently, we haven´t done a specific update in the code that affects this, but we are migrating our Rails and mysql to a newer version at the moment in development. So, I wonder if it´s related to this, however, am not able to see where exactly the problem is.
Please let see the two different behaviours with an example:
We will send the same sample message in both environmets, so in our textarea we write:
This is a test message
with a some break lines.
Lorem ipsum whatever.
This is the text message that is sent to be stored in a varchar field in my mysql database: This is a test messagennwith a some break lines.nnLorem ipsum whatever.
This is the text that I can see stored in both development and production database: This is a test message with a some break lines. Lorem ipsum whatever.
This is the template to send the email in both development and production (no changes here): <p class="p1" style="white-space: pre-wrap;"><%= @offer.message_pre_offer %></p>
This is the log that I see when the message is sent by email in development:
<p class=3D"p1" style=3D"white-space: pre-wrap; margin: 1em 0; padding: 0=
; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #606=
060; font-family: Source Sans Pro, Helvetica Neue, Helvetica, Arial, sans=
-serif; font-size: 15px; line-height: 150%; font-weight: 300;" align=3D"l=
eft">This is a test message=0D
=0D
with a some break lines.=0D
=0D
Lorem ipsum whatever.</p>=0D
<style>=0D
Unfortunately I cannot see this detailed log in production because the debug level is not set to debug.
When I open the email that the test user is got in gmail in webmail, this is the code that I can see in dev tools in Chrome:
Development working wrong:
<p style="white-space:pre-wrap;margin:1em 0;padding:0;color:#606060;font-family:Source Sans Pro,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:15px;line-height:150%;font-weight:300" align="left">This is a test message
with a some break lines.
Lorem ipsum whatever.</p>
This is how it looks in gmail webmail:
Production working fine:
<p style="color:#606060;font-family:Source Sans Pro,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:15px;font-weight:300;line-height:150%;margin:1em 0;padding:0;text-align:left;white-space: pre-line;" align="left">This is a test message
with a some break lines.
Lorem ipsum whatever.</p>
This is how it looks in production:
Probably it´s not related at all, buy my rails versions are:
-
Development: Rails 5.2.4, mysql 8.0.18
-
Production: Rails 4.4.0, mysql Ver 14.14 Distrib 5.5.40, for debian-linux-gnu (x86_64) using readline 6.3
2
Answers
This is likely to explain the extra vertical spacing:
Windows uses CR LF for line breaks.
Unix systems use LF.
Macintosh uses CR.
When you display one form of line break on a system that is expecting a different form, a mess can occur.
Perhaps the “right” design uses only LF, then changes or expands as needed depending on the target machine. Note that
<br>
is the equivalent for HTML, where CR and LF are simply “white space”.See also
<pre>
and PHP’sNL2BR()
and probably other things.What templating engine are you using to generate the emails, and do the inlining of CSS?
I suspect that’s related to the problem here, because the
style
output for development and production differ in the examples you’ve given.In particular, development has
white-space: pre-wrap
and production haswhite-space: pre-line
. This is important becausepre-line
will condense multiple newline characters into a single newline, whereaspre-wrap
will preserve all of them.This hopefully explains why you are seeing different behaviour in production vs development, but you likely want to preserve all whitespace that the user types in. In this case, you can ensure consistent spacing by replacing instances
r
andrn
with justn
e.g.
user_input.gsub(/rn?/, "n")