md2plain
Convert Markdown letters to plain-text email bodies. Copy to the macOS or Linux Wayland clipboard, save a UTF-8 file, or write to stdout.
Install
Python 3.10+.
uv tool install md2plain
uv tool upgrade md2plain
Linux clipboard support requires wl-clipboard and a working Wayland session.
On Debian/Ubuntu:
sudo apt install wl-clipboard
File and stdout output need no clipboard backend. X11 and Windows clipboard backends are not supported.
Usage
md2plain letter.md # copy
md2plain letter.md --print # stdout
md2plain letter.md -o letter.txt # save
md2plain letter.md -o ~/Documents/letters/ # save as letter.txt
md2plain letter.md -o letter.txt --copy # save and copy
md2plain letter.md --watch -o letter.txt # update file on save
cat letter.md | md2plain - --print # stdin
-o and --print disable default copying. Add --copy to copy as well.
--print -o FILE prints and saves.
0.2.0: replace the old save-and-copy usage with -o FILE --copy.
Options
| Option | Description |
|---|---|
-o, --output FILE_OR_DIR |
Save to a file or directory |
--print |
Write to stdout |
--copy |
Enable copying with other outputs |
--no-copy |
Disable copying; mutually exclusive with --copy |
--watch |
Update after the input stays stable for 0.5 seconds |
--width N |
Target display width; default 75, minimum 1 |
--soft-breaks |
Join paragraph soft line breaks |
--version |
Show version |
Files
- Input and output use UTF-8; an input BOM is accepted. Paths support
~. - Existing output directories produce
INPUT_STEM.txt. New directories require a trailing/; otherwise a nonexistent path is a filename. - Missing parent directories are created after successful conversion.
letter.draft.mdbecomesletter.draft.txt. For stdin,-orequires a filename. - Any suffix is accepted; output remains plain text.
- Saves are atomic and preserve existing permissions. Input/output aliases are rejected. A copy failure leaves the saved file intact and reports an error.
Rendering
- Wrap ordinary text at 75 display columns by default; URLs, email addresses, and code may exceed the target.
- Preserve link targets, code whitespace,
~~strikethrough~~, and exact--signature separators. Keep source line breaks unless--soft-breaksis set. - Keep aligned tables that fit; render wider tables as
header: valuerecords. Images become text references to their source.
Use your mail client's plain-text compose mode. The client controls MIME and sending; display columns are not email transport line limits.
Example Markdown · Plain-text output
Watching
Watch mode requires a file. Temporary empty or invalid input keeps the last successful output. Wayland clipboard contents survive command and watch exit. Wayland copying times out after five seconds.
Inherited WAYLAND_SOCKET connections are supported. Anonymous connections
allow one-shot copying only; watching requires a reconnectable endpoint.
Development
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/python -m unittest discover -s tests -v
.venv/bin/ruff check src tests
.venv/bin/black --check src tests
Real Wayland tests require Sway and wl-clipboard. They start a private headless
session and run separately in Ubuntu CI:
MD2PLAIN_WAYLAND_TEST=1 .venv/bin/python -m unittest discover \
-s tests -p test_wayland_integration.py -v
Metadata
Release files for md2plain 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| md2plain-0.2.0.tar.gz | 35.0 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| md2plain-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 50.9 kB
Release files / md2plain-0.2.0.tar.gz
| Download URL | md2plain-0.2.0.tar.gz |
|---|---|
| Size | 35.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4f2c86b3271f4329d10a38e19be343716d9f5c1517c8f7f27c38d351f67c60bb
|
|
BLAKE2b-256 checksum How to use checksums |
69f0d438f38cda359544a45e4b2ccefc1dd6604678e0dc582bde235b078d723d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logRelease files / md2plain-0.2.0-py3-none-any.whl
| Download URL | md2plain-0.2.0-py3-none-any.whl |
|---|---|
| Size | 15.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7ef2814eea67106a1f440a7283d2086042a1d4be499a4c0cbf3aa138ae9638ce
|
|
BLAKE2b-256 checksum How to use checksums |
510bb9a45bf0d71d28958a5d6760ce0c1ab946d5d3ae15cc9afc3270219fad01
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logSecurity for md2plain 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for md2plain-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.