Skip to main content

Better line wrapping and formatting for plaintext and Markdown

Project description

flowmark

Flowmark is a new Python implementation of text and Markdown line wrapping and filling, with an emphasis on making git diffs and LLM edits to text documents easier to diff and review.

In addition, it offers Markdown auto-formatting and normalization as a library or from the command line. This is much like markdownfmt or prettier's Markdown support but is pure Python and has (in my humble opinion) better options and defaults.

Installation

The simplest way to use the tool is to use uv. Then run uvx flowmark --help.

To install the command-line properly:

uv tool install flowmark

Or pipx:

pipx install flowmark

Then

flowmark --help

To use as a library, use uv/poetry/pip to install flowmark.

Use in VSCode/Cursor

You can use Flowmark to auto-format Markdown on save in VSCode or Cursor. Install the "Run on Save" (emeraldwalk.runonsave) extension. Then add to your settings.json:

  "emeraldwalk.runonsave": {
    "commands": [
        {
            "match": "\\.md$",
            "cmd": "flowmark --auto ${file}"
        }
    ]
  }

The --auto option is just the same as --inplace --nobackup --semantic.

Use Cases

The main ways to use Flowmark are:

  • To autoformat Markdown on save in VSCode/Cursor or any other editor that supports running a command on save. Flowmark uses a readable format that makes diffs easy to read and use on GitHub. It also normalizes all Markdown syntax variations (such as different header or formatting styles). This can be especially useful for documentation and editing workflows where clean diffs and minimal merge conflicts on GitHub are important.

  • As a command line formatter to format text or Markdown files using the flowmark command.

  • As a library to autoformat Markdown. For example, it is great to normalize the outputs from LLMs to be consistent, or to run on the inputs and outputs of LLM transformations that edit text, so that the resulting diffs are clean. Having this as a simple Python library makes this easy in AI-related document pipelines.

  • As a drop-in replacement library for Python's default textwrap but with more options. It simplifies and generalizes that library, offering better control over initial and subsequent indentation and when to split words and lines, e.g. using a word splitter that won't break lines within HTML tags.

Other features:

  • Flowmark has the option to to use semantic line breaks (using a heuristic to break lines on sentences sentences when that is reasonable), which is an underrated feature that can make diffs on GitHub much more readable. The the change may seem subtle but avoids having paragraphs reflow for very small edits, which does a lot to minimize merge conflicts. An example of what sentence-guided wrapping looks like, see the Markdown source of this readme file.)

  • Very simple and fast regex-based sentence splitting. It's just based on letters and punctuation so isn't perfect but works well for these purposes (and is much faster and simpler than a proper sentence parser like SpaCy). It should work fine for English and many other latin/Cyrillic languages but hasn't been tested on CJK.

It aims to be small and simple and have only a few dependencies, currently only marko, regex, and strif.

Because YAML frontmatter is common on Markdown files, the Markdown autoformat preserves all frontmatter (content between --- delimiters at the front of a file).

Why a New Markdown Formatter?

Previously I'd implemented something very similar with for Atom. I found the Markdown formatting conventions enforced by the that plugin worked really well for editing and publishing large or collaboratively edited documents.

This is new, pure Python implementation. There are numerous needs for a tool like this on the command line and in Python.

With LLM tools now using Markdown everywhere, there are enormous advantages to having very clean and well-formatted Markdown documents, since you can then cleanly see diffs or edits made by LLMs.

If you are in a workspace where you are editing lots of text, having them all be Markdown with frontmatter, auto-formatted for every git commit makes for a much better experience.

Usage

Flowmark can be used as a library or as a CLI.

usage: flowmark [-h] [-o OUTPUT] [-w WIDTH] [-p] [-s] [-c] [-i] [--nobackup] [--auto]
                [--version]
                [file]

Flowmark: Better line wrapping and formatting for plaintext and Markdown

positional arguments:
  file                 Input file (use '-' for stdin)

options:
  -h, --help           show this help message and exit
  -o, --output OUTPUT  Output file (use '-' for stdout)
  -w, --width WIDTH    Line width to wrap to
  -p, --plaintext      Process as plaintext (no Markdown parsing)
  -s, --semantic       Enable semantic (sentence-based) line breaks (only applies to
                       Markdown mode)
  -c, --cleanups       Enable (safe) cleanups for common issues like accidentally
                       boldfaced section headers (only applies to Markdown mode)
  -i, --inplace        Edit the file in place (ignores --output)
  --nobackup           Do not make a backup of the original file when using --inplace
  --auto               Same as `--inplace --nobackup --semantic --cleanups`, as a
                       convenience for fully auto-formatting files
  --version            Show version information and exit

Flowmark provides enhanced text wrapping capabilities with special handling for
Markdown content. It can:

- Format Markdown with proper line wrapping while preserving structure
  and normalizing Markdown formatting

- Optionally break lines at sentence boundaries for better diff readability

- Process plaintext with HTML-aware word splitting

It is both a library and a command-line tool.

Command-line usage examples:

  # Format a Markdown file to stdout
  flowmark README.md

  # Format a Markdown file and save to a new file
  flowmark README.md -o README_formatted.md

  # Edit a file in-place (with or without making a backup)
  flowmark --inplace README.md
  flowmark --inplace --nobackup README.md

  # Process plaintext instead of Markdown
  flowmark --plaintext text.txt

  # Use semantic line breaks (based on sentences, which is helpful to reduce
  # irrelevant line wrap diffs in git history)
  flowmark --semantic README.md

For more details, see: https://github.com/jlevy/flowmark

Other Notes

Project Docs

For how to install uv and Python, see installation.md.

For development workflows, see development.md.

For instructions on publishing to PyPI, see publishing.md.


This project was built from simple-modern-uv.

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

flowmark-0.4.3.tar.gz (123.9 kB view details)

Uploaded Source

Built Distribution

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

flowmark-0.4.3-py3-none-any.whl (23.5 kB view details)

Uploaded Python 3

File details

Details for the file flowmark-0.4.3.tar.gz.

File metadata

  • Download URL: flowmark-0.4.3.tar.gz
  • Upload date:
  • Size: 123.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for flowmark-0.4.3.tar.gz
Algorithm Hash digest
SHA256 4918007cf2355b64bf72e18f0b36925d09b0769b65ce0ed13cf9cac7ec8ee2ec
MD5 60d142334735032a6061c2cd06784f53
BLAKE2b-256 cfa38a05408255ebfdfce88e114d9820990f3621869ed33fac42dd884735c8e7

See more details on using hashes here.

Provenance

The following attestation bundles were made for flowmark-0.4.3.tar.gz:

Publisher: publish.yml on jlevy/flowmark

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file flowmark-0.4.3-py3-none-any.whl.

File metadata

  • Download URL: flowmark-0.4.3-py3-none-any.whl
  • Upload date:
  • Size: 23.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for flowmark-0.4.3-py3-none-any.whl
Algorithm Hash digest
SHA256 170c81f2032f50e8a6d5cbaead0fd9874e9a59aa0cf3c6d29e4353d3536d581a
MD5 96d59da06607c7661d15bd75c40803a3
BLAKE2b-256 23e1c7c522a87be366ef4954ed179fce3a82eebb02b9f77901607b72b3baa887

See more details on using hashes here.

Provenance

The following attestation bundles were made for flowmark-0.4.3-py3-none-any.whl:

Publisher: publish.yml on jlevy/flowmark

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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