Skip to main content

Plain text email formatter

Project description

Mail Format

mailfmt is a simple plain text email formatter. It's designed to ensure consistent paragraph spacing while preserving markdown syntax, email headers, sign-offs, and signature blocks.

By default, the command accepts its input on stdin and prints to stdout. This makes it well suited for use as a formatter with a text editor like Kakoune or Helix.

Features

  • Wraps emails at specified columns.
  • Automatically reflows paragraphs.
  • Squashes consecutive paragraph breaks.
  • Preserves:
    • Any long word not broken by spaces (e.g. URLs, email addresses).
    • Quoted lines.
    • Indented lines.
    • Lists.
    • Markdown-style code blocks.
    • Usenet-style signature block at EOF.
    • Sign-offs.
  • If specified, output can be made safe for passing to a Markdown renderer.
    • Use case: piping the output to pandoc to write a text/html message. See Markdown Safety.

Installation

mailfmt is intended for use as a standaole tool. The package is available on PyPI as mailfmt. I recommend using uv or pipx to install it so the mailfmt command is available on your path:

uv tool install mailfmt

Verify that the installation was successful:

mailfmt --help

The tool doesn't currently have any dependencies. Therefore, you can just download and execute the mailfmt script directly. However, dependencies may be introduced later, so I recommend installing with a Python package manager.

Usage

usage: mailfmt [-h] [-w WIDTH] [-b] [--no-replace-whitespace] [--no-reflow]
               [--no-signoff] [--no-signature] [--no-squash] [-m] [-i INPUT]
               [-o OUTPUT]

Formatter for plain text email.
"--no-*" options are NOT passed by default.

options:
  -h, --help            show this help message and exit
  -w, --width WIDTH     Text width for wrapping. (default: 74)
  -b, --break-long-words
                        Break long words while wrapping. (default: False)
  --no-replace-whitespace
                        Don't normalize whitespace when wrapping.
  --no-reflow           Don't reflow lines.
  --no-signoff          Don't preserve signoff line breaks.
  --no-signature        Don't preserve signature block.
  --no-squash           Don't squash consecutive paragraph breaks.
  -m, --markdown-safe   Output format safe for Markdown rendering.
  -i, --input INPUT     Input file. (default: STDIN)
  -o, --output OUTPUT   Output file. (default: STDOUT)

Author : Daniel Fichtinger
License: ISC
Contact: daniel@ficd.ca

Output Example

Before:

Hey,

This is a really long paragraph with lots of words in it. However, my text editor uses soft-wrapping, so it ends up looking horrible when viewed without wrapping! Additionally,
if I manually add some line breaks, things start to look _super_ janky!

I can't just pipe this to `fmt` because it may break my beautiful
markdown
syntax. Markdown formatters are also problematic because they mess up
my signoff and signature blocks! What should I do?

Best wishes,
Daniel

-- 
Daniel
sr.ht/~ficd
daniel@ficd.ca

After:

Hey,

This is a really long paragraph with lots of words in it. However, my text
editor uses soft-wrapping, so it ends up looking horrible when viewed
without wrapping! Additionally, if I manually add some line breaks, things
start to look _super_ janky!

I can't just pipe this to `fmt` because it may break my beautiful markdown
syntax. Markdown formatters are also problematic because they mess up my
signoff and signature blocks! What should I do?

Best wishes,
Daniel

-- 
Daniel
sr.ht/~ficd
daniel@ficd.ca

Markdown Safety

In some cases, you may want to generate an HTML email. Ideally, you'd want the HTML to be generated directly from the plain text message, and for both versions to be legible and have the same semantics.

Although mailfmt was written with Markdown markup in mind, its intended output is still the text/plain format. If you pass its output directly to a Markdown renderer, line breaks in sign-offs and the signature block won't be preserved.

If you invoke mailfmt --markdown-safe, then \ characters will be appended to mark line breaks that would otherwise be squashed, making the output suitable for conversion into HTML. Here's an example of one such pipeline:

cat message.txt | mailfmt --markdown-safe | pandoc -f markdown -t html
--standalone > message.html

Here's the earlier example message with markdown safe output:

Hey,

This is a really long paragraph with lots of words in it. However, my text
editor uses soft-wrapping, so it ends up looking horrible when viewed
without wrapping! Additionally, if I manually add some line breaks, things
start to look _super_ janky!

I can't just pipe this to `fmt` because it may break my beautiful markdown
syntax. Markdown formatters are also problematic because they mess up my
signoff and signature blocks! What should I do?

Best wishes, \
Daniel \

--  \
Daniel \
sr.ht/~ficd \
daniel@ficd.ca \

Aerc Integration

For integration with aerc, consider adding the following to your aerc.conf:

[multipart-converters]
text/html=mailfmt --markdown-safe | pandoc -f markdown -t html --standalone

When you're done writing your email, you can call the :multipart text/html command to generate a multipart/alternative message which includes both your original text/plain and the newly generated text/html content.

Contributing

Please send patches, requests, and concerns to my public inbox.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mailfmt-1.0.0.tar.gz (6.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mailfmt-1.0.0-py3-none-any.whl (6.0 kB view details)

Uploaded Python 3

File details

Details for the file mailfmt-1.0.0.tar.gz.

File metadata

  • Download URL: mailfmt-1.0.0.tar.gz
  • Upload date:
  • Size: 6.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.10

File hashes

Hashes for mailfmt-1.0.0.tar.gz
Algorithm Hash digest
SHA256 2d572ee65b35cbdb8a625490bcfa67d75a84c87e6ec9165d5159ac13658309c9
MD5 fa50dee0b81ee1a374240d915688d63d
BLAKE2b-256 b038296c439f8abe2262a5b8bc2e87fcf9d57707a8d04180e3bace534aaa51b8

See more details on using hashes here.

File details

Details for the file mailfmt-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: mailfmt-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 6.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.10

File hashes

Hashes for mailfmt-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d0fb79b091b477aa5206c37fbe93bd9f434676a25edc401a3ee5e361ce9f5828
MD5 d5985c6908f36831f1e898b0dc7b688a
BLAKE2b-256 e3dea629d31eca750bae248af686bd97405da9a1fafc911c53029ca91ab38524

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page