Compare commits

..

1 commit
main ... pkg2

Author SHA1 Message Date
0cad9c91c3 packaged for pypi 2025-06-04 13:11:29 -04:00
6 changed files with 48 additions and 119 deletions

View file

@ -1,20 +0,0 @@
on:
push:
tags:
- 'v*'
jobs:
publish:
runs-on: based-alpine
steps:
- uses: actions/checkout@v4
- name: setup cache
id: uv-cache
uses: https://git.ficd.sh/ficd/uv-cache@v1
- name: build
run: |
uv sync
uv build
- name: publish
run: |
uv publish --token ${{ secrets.PYPI_TOKEN }}

View file

@ -1,21 +1,22 @@
<h1>Mail Format</h1> <h1>Mail Format</h1>
`mailfmt` is a simple plain text email formatter. It's designed to ensure `mailfmt` is a simple plain text email formatter. It's designed to ensure
consistent paragraph spacing while preserving markdown syntax, email consistent paragraph spacing while preserving markdown syntax, email headers,
headers, sign-offs, and signature blocks. sign-offs, and signature blocks.
By default, the command accepts its input on `stdin` and prints to By default, this script accepts its input on `stdin` and prints to `stdout`.
`stdout`. This makes it well suited for use as a formatter with a text This makes it well suited for use as a formatter with a text editor like Kakoune
editor like Kakoune or Helix. or Helix. It has no dependencies besides the standard Python interpreter, and
was written and tested against Python 3.13.3.
<!--toc:start--> <!--toc:start-->
- [Features](#features) - [Features](#features)
- [Installation](#installation)
- [Usage](#usage) - [Usage](#usage)
- [Output Example](#output-example) - [Output Example](#output-example)
- [Markdown Safety](#markdown-safety) - [Markdown Safety](#markdown-safety)
- [Aerc Integration](#aerc-integration) - [Aerc Integration](#aerc-integration)
- [Contributing](#contributing)
<!--toc:end--> <!--toc:end-->
@ -32,27 +33,9 @@ editor like Kakoune or Helix.
- Markdown-style code blocks. - Markdown-style code blocks.
- Usenet-style signature block at EOF. - Usenet-style signature block at EOF.
- Sign-offs. - Sign-offs.
- If specified, output can be made safe for passing to a Markdown - If specified, output can be made safe for passing to a Markdown renderer.
renderer. - Use case: piping the output to `pandoc` to write a `text/html` message. See
- Use case: piping the output to `pandoc` to write a `text/html` [Markdown Safety](#markdown-safety).
message. See [Markdown Safety](#markdown-safety).
## Installation
`mailfmt` is intended for use as a standaole tool. The package is
available on PyPI as `mailfmt`. I recommend using
[uv](https://github.com/astral-sh/uv) or `pipx` to install it so the
`mailfmt` command is available on your path:
```sh
uv tool install mailfmt
```
Verify that the installation was successful:
```sh
mailfmt --help
```
## Usage ## Usage
@ -80,7 +63,8 @@ options:
-o, --output OUTPUT Output file. (default: STDOUT) -o, --output OUTPUT Output file. (default: STDOUT)
Author : Daniel Fichtinger Author : Daniel Fichtinger
Contact: daniel@ficd.sh License: ISC
Contact: daniel@ficd.ca
``` ```
## Output Example ## Output Example
@ -103,7 +87,8 @@ Daniel
-- --
Daniel Daniel
daniel@ficd.sh sr.ht/~ficd
daniel@ficd.ca
``` ```
After: After:
@ -125,24 +110,23 @@ Daniel
-- --
Daniel Daniel
daniel@ficd.sh sr.ht/~ficd
daniel@ficd.ca
``` ```
## Markdown Safety ## Markdown Safety
In some cases, you may want to generate an HTML email. Ideally, you'd want In some cases, you may want to generate an HTML email. Ideally, you'd want the
the HTML to be generated directly from the plain text message, and for HTML to be generated directly from the plain text message, and for _both_
_both_ versions to be legible and have the same semantics. versions to be legible and have the same semantics.
Although `mailfmt` was written with Markdown markup in mind, its intended Although `mailfmt` was written with Markdown markup in mind, its intended output
output is still the `text/plain` format. If you pass its output directly is still the `text/plain` format. If you pass its output directly to a Markdown
to a Markdown renderer, line breaks in sign-offs and the signature block renderer, line breaks in sign-offs and the signature block won't be preserved.
won't be preserved.
If you invoke `mailfmt --markdown-safe`, then `\` characters will be If you invoke `mailfmt --markdown-safe`, then `\` characters will be appended to
appended to mark line breaks that would otherwise be squashed, making the mark line breaks that would otherwise be squashed, making the output suitable
output suitable for conversion into HTML. Here's an example of one such for conversion into HTML. Here's an example of one such pipeline:
pipeline:
```bash ```bash
cat message.txt | mailfmt --markdown-safe | pandoc -f markdown -t html cat message.txt | mailfmt --markdown-safe | pandoc -f markdown -t html
@ -168,20 +152,24 @@ Daniel \
-- \ -- \
Daniel \ Daniel \
daniel@ficd.sh \ sr.ht/~ficd \
daniel@ficd.ca \
``` ```
## Aerc Integration ## Aerc Integration
For integration with `aerc`, consider adding the following to your For integration with `aerc`, consider adding the following to your `aerc.conf`:
`aerc.conf`:
```ini ```ini
[multipart-converters] [multipart-converters]
text/html=mailfmt --markdown-safe | pandoc -f markdown -t html --standalone text/html=mailfmt --markdown-safe | pandoc -f markdown -t html --standalone
``` ```
When you're done writing your email, you can call the When you're done writing your email, you can call the `:multipart text/html`
`:multipart text/html` command to generate a `multipart/alternative` command to generate a `multipart/alternative` message which includes _both_ your
message which includes _both_ your original `text/plain` _and_ the newly original `text/plain` _and_ the newly generated `text/html` content.
generated `text/html` content.
## Contributing
Please send patches, requests, and concerns to my
[public inbox](https://lists.sr.ht/~ficd/public-inbox).

View file

@ -1,21 +0,0 @@
clean:
#!/bin/sh
if [ ! -d "dist" ] && [ ! -d "__pycache__" ]; then
echo "Nothing to clean."
exit 0
fi
if [ -d "dist" ]; then
echo "Removing dist/"
rm -r dist/
fi
if [ -d "__pycache__" ]; then
echo "Removing __pycache__/"
rm -r "__pycache__"
fi
publish:
#!/bin/sh
just clean
uv build
export UV_PUBLISH_TOKEN="$(pass show pypi)"
uv publish

View file

@ -11,11 +11,10 @@
# Author: Daniel Fichtinger # Author: Daniel Fichtinger
# License: ISC # License: ISC
import argparse
import re
import sys
import textwrap import textwrap
from importlib.metadata import version import sys
import re
import argparse
def main() -> None: def main() -> None:
@ -76,7 +75,7 @@ def main() -> None:
if not signoff_cache and 1 <= n <= 5 and line[-1] == ",": if not signoff_cache and 1 <= n <= 5 and line[-1] == ",":
return True return True
# second potential line # second potential line
elif signoff_cache and 1 <= n <= 5: elif signoff_cache and 1 <= n <= 5 and line[-1].isalpha():
for w in words: for w in words:
if not w[0].isupper(): if not w[0].isupper():
return False return False
@ -85,22 +84,14 @@ def main() -> None:
return False return False
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Heuristic formatter for plain text email. Preserves markup, signoffs, and signature blocks.", description='Formatter for plain text email.\n"--no-*" options are NOT passed by default.',
epilog=""" epilog="""
Author : Daniel Fichtinger Author : Daniel Fichtinger
Repository: https://git.ficd.sh/ficd/mailfmt License: ISC
License : ISC Contact: daniel@ficd.ca
Contact : daniel@ficd.sh
""", """,
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
) )
parser.add_argument(
"-v",
"--version",
required=False,
help="Print version info and exit.",
action="store_true",
)
parser.add_argument( parser.add_argument(
"-w", "-w",
"--width", "--width",
@ -170,9 +161,6 @@ Contact : daniel@ficd.sh
help="Output file. (default: %(default)s)", help="Output file. (default: %(default)s)",
) )
args = parser.parse_args() args = parser.parse_args()
if args.version:
print(version("mailfmt"))
exit(0)
width = args.width width = args.width
should_check_signoff = args.no_signoff should_check_signoff = args.no_signoff
should_check_signature = args.no_signature should_check_signature = args.no_signature

View file

@ -1,19 +1,13 @@
[project] [project]
name = "mailfmt" name = "mailfmt"
version = "1.0.4" version = "0.1.0"
description = "Heuristic plain text email formatter." description = "Add your description here"
readme = "README.md" readme = "README.md"
authors = [ authors = [
{ name = "Daniel Fichtinger", email = "daniel@ficd.sh" } { name = "Daniel Fichtinger", email = "daniel@ficd.ca" }
] ]
requires-python = ">=3.11" requires-python = ">=3.11"
dependencies = [] dependencies = []
license = "ISC"
license-files = ["LICENSE"]
keywords = ["email", "formatter", "cli"]
[project.urls]
Repository = "https://git.ficd.sh/ficd/mailfmt"
[project.scripts] [project.scripts]
mailfmt = "mailfmt:main" mailfmt = "mailfmt:main"

2
uv.lock generated
View file

@ -4,5 +4,5 @@ requires-python = ">=3.11"
[[package]] [[package]]
name = "mailfmt" name = "mailfmt"
version = "1.0.3" version = "0.1.0"
source = { editable = "." } source = { editable = "." }