Skip to main content

Better auto-formatting and line wrapping for Markdown and plaintext

Project description

flowmark

Flowmark is a pure Python Markdown auto-formatter designed for better LLM workflows, clean git diffs, and flexible use from CLI, from IDEs, or as a library.

With AI tools increasingly using Markdown, having consistent, diff-friendly formatting has become essential for modern writing, editing, and document processing workflows. Normalizing Markdown formatting greatly improves collaborative editing and LLM workflows, especially when committing documents to git repositories.

You can use Flowmark as a CLI, as an autoformatter in your IDE, or as a Python library.

The key differences from other Markdown formatters:

  • Carefully chosen default formatting rules that are effective for use in editors/IDEs, in LLM pipelines (and also when paging through docs in a terminal), including normalizing all whitespace, headings, line wrapping, tables, and footnotes.

  • “Just works” support for GFM-style tables, footnotes, and YAML frontmatter.

  • Advanced and customizable line-wrapping capabilities, including semantic line breaks, a feature that is especially helpful in allowing collaborative edits on a Markdown document while avoiding git conflicts.

  • Optional automatic smart quotes for professional-looking typography.

Flowmark aims to be conservative about changes so that it is safe to run automatically on save or after any stage of a document pipeline.

It supports CommonMark and GitHub-Flavored Markdown (GFM) via Marko.

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

Installation

The simplest way to use the tool is to use uv.

Run with uvx flowmark --help or install it as a tool:

uv tool install --upgrade flowmark

Then

flowmark --help

For use in Python projects, add the flowmark package via uv, poetry, or pip.

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. See below for recommended VSCode/Cursor setup.

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

  • As a library to autoformat Markdown from document pipelines. 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.

  • As a more powerful 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. See wrap_paragraph_lines.

Semantic Line Breaks

[!TIP]

For an example of what an auto-formatted Markdown doc looks with semantic line breaks looks like, see the Markdown source of this readme file.

Some Markdown auto-formatters never wrap lines, while others wrap at a fixed width.

Flowmark supports both, via the --width option. Default behavior is 88 columns (like Black and a few other tools).

However, unlike traditional formatters, Flowmark also offers the option to use a heuristic that prefers line breaks at sentence boundaries. This is a small change that can dramatically improve diff readability when collaborating or working with AI tools.

This idea of semantic line breaks, which is breaking lines in ways that make sense logically when possible (much like with code) is an old one. But it usually requires people to agree on how to break lines, which is both difficult and sometimes controversial.

However, now we are using versioned Markdown more than ever, it’s a good time to revisit this idea, as it can make diffs in git much more readable. The change may seem subtle but avoids having paragraphs reflow for very small edits, which does a lot to minimize merge conflicts.

This is my own refinement of the (fairly loose) semantic line break specification. Instead of just allowing you to break lines as you wish, it simply auto-applies fixed conventions about likely sentence boundaries in a reasonable way. It uses very simple and fast regex-based sentence splitting. While not perfect, this 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.

While this approach to line wrapping may not be familiar, I suggest you just try flowmark --auto on a document and you will begin to see the benefits as you edit/commit documents.

This feature is enabled with the --semantic flag or the --auto convenience flag.

Smart Quote Support

Flowmark offers optional automatic smart quotes to convert "non-oriented quotes" to “oriented quotes” and apostrophes intelligently.

This is a robust way to ensure Markdown text can be converted directly to HTML with professional-looking typography.

Smart quotes are applied conservatively and won’t affect code blocks, so they don’t break code snippets. It only applies them within single paragraphs of text, and only applies to ' and " quote marks around regular text.

This feature is enabled with the --smartquotes flag or the --auto convenience flag.

Frontmatter Support

Because YAML frontmatter is common on Markdown files, any YAML frontmatter (content between --- delimiters at the front of a file) is always preserved exactly. YAML is not normalized.

[!TIP]

See the frontmatter format repo for more discussion of YAML frontmatter and its benefits.

Usage

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

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

Flowmark: Better auto-formatting and line wrapping for Markdown and plaintext

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, or 0 to disable line wrapping
                       (default: 88)
  -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)
  --smartquotes        Convert straight quotes to typographic (curly) quotes and
                       apostrophes (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
                       --smartquotes`, 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

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|\\.md\\.jinja|\\.mdc)$",
            "cmd": "flowmark --auto ${file}"
        }
    ]
  }

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

Why Another Markdown Formatter?

There are several other Markdown auto-formatters:

  • markdownfmt is one of the oldest and most popular Markdown formatters and works well for basic formatting.

  • mdformat is probably the closest alternative to Flowmark and it also uses Python. It preserves line breaks in order to support semantic line breaks, but does not auto-apply them as Flowmark does.

  • Prettier is the ubiquitous Node formatter that handles Markdown/MDX

  • dprint-plugin-markdown is a Markdown plugin for dprint, the fast Rust/WASM engine

  • Rule-based linters like markdownlint-cli2 catch violations or sometimes fix, but tend to be far too clumsy in my experience.

  • Finally, the remark ecosystem is by far the most powerful library ecosystem for building your own Markdown tooling in JavaScript/TypeScript. You can build auto-formatters with it but there isn’t one that’s broadly used as a CLI tool.

All of these are worth looking at, but none offer the more advanced line breaking features of Flowmark or seemed to have the “just works” CLI defaults and library usage I found most useful.

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.9.tar.gz (175.6 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.9-py3-none-any.whl (29.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: flowmark-0.4.9.tar.gz
  • Upload date:
  • Size: 175.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.7.13

File hashes

Hashes for flowmark-0.4.9.tar.gz
Algorithm Hash digest
SHA256 13354f3b51df837038640026ab0e68aaa48e1891e1c9060106b0c43d05433cda
MD5 46ce7cc570859932e1dfab25e87e0f9b
BLAKE2b-256 0cca47475405960bce3ba0f659a9205881baf58bb10c4bcb3edd691c0a6e99e0

See more details on using hashes here.

File details

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

File metadata

  • Download URL: flowmark-0.4.9-py3-none-any.whl
  • Upload date:
  • Size: 29.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.7.13

File hashes

Hashes for flowmark-0.4.9-py3-none-any.whl
Algorithm Hash digest
SHA256 21e78a54ee51d7a7f41524efe33fa91cb889e9f8b995ea14ccc1efbc5e1e4475
MD5 c69a8f094df61cf16801b1916832f32c
BLAKE2b-256 fd4d7333602bdfff13703e695b98329fc47aadd10f7ccb63923a149c6a788541

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