MailFlow is a plugin for Apple Mail on OS X 10.12 and later, fixing it to
emit RFC2646 format=flowed plain text messages and taming its enthusiasm for
quoted-printable transfer encoding. Quoting and attribution when replying is
also improved, and a long-standing bug in the display of plain text messages
is fixed.

Mail was once quite a good 'net citizen. It could be configured to generate
plain text email, and would do so with the text neatly wrapped at 76
columns. In addition, it used the RFC2646 format=flowed extension to
indicate that these wrapped paragraphs could be reflowed. Thus mailing list
archives and traditional mail clients saw readable 80-column text without
noisy encoding, but more sophisticated readers could re-fill the paragraphs
to suit the display width.

Unfortunately, Mail is poorly maintained and has declined in quality over
recent years, with many bugs introduced and incompetent design choices made.
Current releases have ditched format=flowed for plain text parts, instead
opting to emit each paragraph as a single long line. If this is longer than
77 characters, the text is mangled with a quoted-printable transfer
encoding. The resulting email leaves a very visible mess in mailing list
archives on the web, as well as drawing understandable ire from recipients
with traditional unix mail clients.

Fortunately, even if Mac users find themselves attracted to Apple Mail for
its convenient reading interface and good platform integration, all is not
lost. Mail has been furnished with a plugin interface, albeit an
undocumented one, and MailFlow hooks into this to improve the situation.


MailFlow is currently compatible with Apple Mail 10.0 and later. To install,
unpack the source tar.gz file, change to the unpacked directory and run

  /usr/bin/python install.py

Plugin bundles contain a list of UUIDs identifying versions of Mail with
which they are compatible. The install.py script extracts the correct UUID
from the installed version of Mail, generates a MailFlow.bundle to match,
and installs it in ~/Library/Mail/Bundles/. You will need to quit and
relaunch Mail for the plugin to be registered.

Sometimes when Mail is updated, its compatibility UUID changes. Mail will
then disable plugins, moving them from 'Bundles/' to 'Bundles (Disabled)/'.
The user is notified when this happens, and it is sufficient to simply run
the install.py script again. The old disabled bundle will be cleared away,
and a new one built and installed to match the new version of Mail.


Most of MailFlow's functionality should be transparent to a Mail user unless
the raw source of sent messages is examined. Its primary feature is to break
paragraphs into reflowable lines in RFC2646 format=flowed format and disable
quoted-printable transfer encoding for plain text email.

In outbound plain text messages, lines are broken at word boundaries to wrap
the text to 76 columns wide, and a trailing space is added wherever a line
has been broken. Where a line to be broken is quoted, the continuation line
is quoted to the same level. Finally, to signal the message has been flowed,
the parameters format=flowed and delsp=yes are added to the text/plain
content-type. The result is a visually clean plain text message, correctly
wrapped for 80 column displays, but clients aware of the format=flowed
extension can spot the trailing spaces, reassemble paragraphs and reflow
them to fit displays of differing widths. This is especially useful for
mobile devices.

Unlike Apple's original format=flowed implementation, MailFlow will never
break a line within a word, even if that word is longer than 76 characters.
This was typically an issue with long URLs pasted into messages: breaking
these to fit an 80-column display usually causes more problems than it
solves, and some format=flowed aware clients do not fully support the
delsp=yes modifier needed to reassemble them. However, as with Apple's
original implementation, MailFlow implements space stuffing for unquoted
lines beginning with ' ' or 'From '.

Lines indented with whitespace are not flowed, whether or not they are
quoted, and any trailing whitespace is removed to avoid clients from trying
to reflow them. This provides a convenient way to include non-reflowable
content such as quotes, code samples, aligned columns or ASCII art whilst
composing a plain text message.

For convenience when indenting text blocks, the built-in Increase/Decrease
Indentation operations are extended to work on plain text messages. These
will insert or remove two spaces at the start of the current line or all
lines overlapping the current selection.

Flowed format is not appropriate for some messages, such as those containing
inline patches. To disable the use of flowed text for an individual message,
hold down the Option key when clicking on the Send button in the toolbar, or
when selecting Send from the Message menu. MailFlow will still restrict
unnecessary use of quoted-printable even when format=flowed is disabled.

By default, Mail uses a quoted-printable transfer encoding for text/plain
parts whenever they contain non-ASCII characters or a line longer than 77
characters. MailFlow relaxes this behaviour for text/plain, using a 7-bit
transfer encoding for plain ASCII and an 8-bit transfer encoding otherwise,
provided the lines do not exceed the 998 column limit imposed by SMTP. Note
the outbound mail server must support the 8BITMIME ESMTP extension
(RFC1653/RFC6152) but all modern SMTP servers are fine with this.

MailFlow will trim the excessively verbose attribution line Mail inserts
when composing a reply, i.e.

  On 8 Apr 2014, at 10:08:34, Chris Webb <chris@arachsys.com> wrote:


  Chris Webb <chris@arachsys.com> wrote:

Since version 8.0, Mail has a bug which causes the attribution line to be
quoted as if it were part of the original message. MailFlow will also fix
this whilst trimming the attribution line.

MailFlow makes it easier to forward messages as proper MIME attachments
instead of quoting them inline. Mail has always supported MIME forward but
relegated it to the Message menu without a shortcut or toolbar button,
instead encouraging ugly inline forward. MailFlow reconfigures the standard
forward buttons, keyboard shortcut and menu item to use MIME.

To override this and forward a message inline, hold down the Option key when
clicking on the Forward button in the toolbar or when selecting Forward from
the Message menu.

Finally, MailFlow addresses a very long-standing bug in Mail, which drops
one leading space from every indented line of a plain text message in the
message viewer. When converting the text/plain part to HTML for display in a
WebView, all but the first leading space is rendered as '&nbsp;' so, for
example, a line '  foo' becomes '<BR> &nbsp;foo'. However, WebKit will then
display this as ' foo' not '  foo'.

To work around this bug, MailFlow translates a space following a '<BR>' (or
at the start of the message) into '&nbsp;' before a plain text part is
rendered in a WebView.


For command-line users, the MailFlow distribution also includes a small
utility, pbmbox. When messages are selected and copied in Mail, they are
added to the clipboard as RFC822MessageDatasPboardType objects. pbmbox
decodes these objects and emits the messages in unix mbox format on stdout.

To install, copy it to a directory in your PATH and make it executable:

  sudo install -m 0755 pbmbox.py /usr/local/bin/pbmbox

A typical use is importing a patch series from email into a git repository.
Select the messages in Mail, copy them with Command-C, and then run

  pbmbox | git am

within the repository.

By default, the mboxrd format is used: lines beginning with />*From / are
quoted with one additional leading '>'. This encoding avoids corruption of
messages and is always reversible. If the -n or --no-quote-from option is
given, pbmbox will not attempt to quote 'From  ' lines. This is sometimes
useful for simple command-line handling of a single message, where no
ambiguity can result from an unquoted 'From '.


This software was written by Chris Webb <chris@arachsys.com> and is
distributed as Free Software under the terms of the MIT license in COPYING.