Search code examples
emailoutlookline-breaks

Send a text/plain email and prevent Outlook from collapsing lines


I send out plain text mails from my web application (e.g. password reset); I'm pretty sure I use proper CRLF line endings all over both header and text. Some lines can be longer than 78 characters, but none more than 998+2.

For some mails, Outlook mail clients collapse the whitespace in the footer parts (after the --  line): despite the CRLF linebreaks are present, they look like being turned into ordinary space characters, giving me a very long line. (edit, clarifying: Linebreaks occur, but not at the intended positions but only as given by the window width.)

Are there methods to tell Outlook to preserve the linebreaks, e.g. some header? Of course I'd prefer a RFC-conforming solution, but it might be OK if it doesn't harm other clients.


Solution

  • I finally found this question and answer, and my solution is: Prepend each newline with a tab character which might be "optimized away" by Outlook, e.g. because it is not followed by another newline.

    If it can be done without too much effort, of course it would help to generate a mail which contains both text/plain and text/html; but if done solely for this reason, it looks like overkill.

    HTML-only mails would work as well, but they are less trustworthy than plain-text mails (because people can be tricked into activating other URLs than the one in the link text), so e.g. SpamAssassin doesn't like them.

    Here is a Python function which inserts a tab before every single line break (but not before sequences of two or more):

    def harden_linebreaks(s):
        tmp = []
        prev = None
        for line in s.splitlines():
            tmp.append((prev, line))
            prev = line
        tmp.append((prev, None))
        res = []
        for tup in tmp:
            line, next = tup
            if (line and next
                and not line.endswith('\t')):
                line += '\t'
            res.append(line)
        return '\n'.join(res[1:])